Em Recursos ocultos de Java, a resposta principal menciona a inicialização com cinta dupla , com uma sintaxe muito atraente:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Esse idioma cria uma classe interna anônima com apenas um inicializador de instância, que "pode usar [...] qualquer método no escopo que o contém".
Pergunta principal: Isso é tão ineficiente quanto parece? Seu uso deve ser limitado a inicializações pontuais? (E, claro, mostrando!)
Segunda pergunta: O novo HashSet deve ser o "this" usado no inicializador de instância ... alguém pode esclarecer o mecanismo?
Terceira pergunta: esse idioma é obscuro demais para ser usado no código de produção?
Resumo: Respostas muito, muito agradáveis, obrigado a todos. Na questão (3), as pessoas acharam que a sintaxe deveria ser clara (embora eu recomende um comentário ocasional, especialmente se o seu código for repassado para desenvolvedores que talvez não estejam familiarizados com ele).
Na pergunta (1), o código gerado deve ser executado rapidamente. Os arquivos .class extras causam confusão no arquivo jar e retardam um pouco a inicialização do programa (obrigado ao @coobird por medir isso). @Thilo apontou que a coleta de lixo pode ser afetada, e o custo de memória para as classes extra carregadas pode ser um fator em alguns casos.
A pergunta (2) acabou sendo mais interessante para mim. Se eu entendo as respostas, o que está acontecendo no DBI é que a classe interna anônima estende a classe do objeto que está sendo construído pelo novo operador e, portanto, possui um valor "this" referente à instância que está sendo construída. Muito arrumado.
No geral, o DBI me parece uma curiosidade intelectual. Coobird e outros salientam que você pode obter o mesmo efeito com Arrays.asList, métodos varargs, Google Collections e os literais Java 7 Collection propostos. Linguagens JVM mais recentes, como Scala, JRuby e Groovy, também oferecem notações concisas para a construção da lista e interoperam bem com o Java. Dado que o DBI atrapalha o caminho da classe, diminui um pouco o carregamento da classe e torna o código um pouco mais obscuro, eu provavelmente evitaria isso. No entanto, pretendo mostrar isso a um amigo que acabou de obter seu SCJP e adora boas justas sobre a semântica Java! ;-) Obrigado a todos!
7/2017: Baeldung tem um bom resumo da inicialização entre chaves e o considera um antipadrão .
12/2017: @Basil Bourque observa que no novo Java 9 você pode dizer:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Esse é certamente o caminho a percorrer. Se você estiver com uma versão anterior, dê uma olhada no ImmutableSet das coleções do Google .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
ser umHashSet
, mas, infelizmente, é uma subclasse anônima.