In Hidden Features of Java la risposta principale menziona Double Brace Initialization , con una sintassi molto allettante:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Questo idioma crea una classe interna anonima con solo un inizializzatore di istanza, che "può usare qualsiasi [...] metodo nell'ambito di contenimento".
Domanda principale: è inefficiente come sembra? Il suo utilizzo dovrebbe essere limitato alle inizializzazioni una tantum? (E ovviamente in mostra!)
Seconda domanda: il nuovo HashSet deve essere il "questo" utilizzato nell'inizializzatore dell'istanza ... qualcuno può far luce sul meccanismo?
Terza domanda: questo idioma è troppo oscuro per essere usato nel codice di produzione?
Riepilogo: risposte molto, molto belle, grazie a tutti. Alla domanda (3), la gente pensava che la sintassi dovesse essere chiara (anche se consiglierei un commento occasionale, specialmente se il tuo codice passerà agli sviluppatori che potrebbero non averne familiarità).
Alla domanda (1), il codice generato dovrebbe essere eseguito rapidamente. I file extra .class causano il disordine dei file jar e rallentano leggermente l'avvio del programma (grazie a @coobird per averlo misurato). @Thilo ha sottolineato che la garbage collection può essere influenzata e il costo della memoria per le classi extra caricate può essere un fattore in alcuni casi.
La domanda (2) si è rivelata molto interessante per me. Se capisco le risposte, quello che sta succedendo in DBI è che la classe interna anonima estende la classe dell'oggetto che viene costruito dal nuovo operatore, e quindi ha un valore "this" che fa riferimento all'istanza in costruzione. Molto pulito.
Nel complesso, DBI mi sembra una sorta di curiosità intellettuale. Coobird e altri sottolineano che è possibile ottenere lo stesso effetto con Arrays.asList, i metodi varargs, le raccolte Google e i letterali della collezione Java 7 proposti. Le lingue JVM più recenti come Scala, JRuby e Groovy offrono anche notazioni concise per la costruzione di elenchi e interagiscono bene con Java. Dato che DBI ingombra il percorso di classe, rallenta un po 'il caricamento della classe e rende il codice un po' più oscuro, probabilmente lo eviterei. Tuttavia, ho in programma di lanciarlo su un amico che ha appena ottenuto il suo SCJP e adora i bravi giullari sulla semantica di Java! ;-) Grazie a tutti!
7/2017: Baeldung ha un buon riassunto dell'inizializzazione del doppio controvento e lo considera un anti-pattern.
12/2017: @Basil Bourque osserva che nel nuovo Java 9 puoi dire:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Questa è sicuramente la strada da percorrere. Se sei bloccato con una versione precedente, dai un'occhiata a ImmutableSet di Google Collections .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
di essere unHashSet
, ma purtroppo è una sottoclasse anonima.