En Versteckte Funktionen von Java die erste Antwort erwähnt Initialisierung der doppelten Klammer , mit einer muy verlockende Syntax:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Dieses Idiom erzeugt eine anonyme innere Klasse, die nur einen Instanzinitialisierer enthält, der "alle [...] Methoden im enthaltenen Bereich verwenden kann".
Die wichtigste Frage: Ist das so ineffizient wie es klingt? Sollte ihre Verwendung auf einmalige Initialisierungen beschränkt werden? (Und natürlich auf Angeberei!)
Zweite Frage: Das neue HashSet muss das "this" sein, das im Instanzinitialisierer verwendet wird ... kann jemand Licht in den Mechanismus bringen?
Dritte Frage: Ist diese Redewendung zu undurchsichtig im Produktionscode zu verwenden?
Zusammenfassung: Sehr, sehr gute Antworten, vielen Dank an alle. Bei Frage (3) waren die Leute der Meinung, dass die Syntax klar sein sollte (obwohl ich einen gelegentlichen Kommentar empfehlen würde, vor allem, wenn Ihr Code an Entwickler weitergegeben wird, die damit vielleicht nicht vertraut sind).
Bei Frage (1) sollte der generierte Code schnell laufen. Die zusätzlichen .class-Dateien verursachen Unordnung in den jar-Dateien und verlangsamen den Programmstart etwas (Dank an @coobird für die Messung). @Thilo wies darauf hin, dass die Garbage Collection beeinträchtigt werden kann, und die Speicherkosten für die zusätzlich geladenen Klassen können in einigen Fällen ein Faktor sein.
Die Frage (2) war für mich am interessantesten. Wenn ich die Antworten verstehe, passiert in DBI, dass die anonyme innere Klasse die Klasse des Objekts erweitert, das durch den new-Operator konstruiert wird, und daher einen "this"-Wert hat, der auf die konstruierte Instanz verweist. Sehr ordentlich.
Insgesamt erscheint mir die DBI als eine Art intellektuelle Kuriosität. Coobird und andere weisen darauf hin, dass man denselben Effekt mit Arrays.asList, varargs-Methoden, Google Collections und den vorgeschlagenen Java 7 Collection-Literalen erzielen kann. Neuere JVM-Sprachen wie Scala, JRuby und Groovy bieten ebenfalls prägnante Notationen für die Listenkonstruktion und arbeiten gut mit Java zusammen. In Anbetracht der Tatsache, dass DBI den Klassenpfad unübersichtlich macht, das Laden von Klassen etwas verlangsamt und den Code ein wenig undurchsichtiger macht, würde ich es wahrscheinlich meiden. Allerdings habe ich vor, dies einem Freund zu empfehlen, der gerade seinen SCJP gemacht hat und sich gerne über die Java-Semantik streitet ;-) Vielen Dank an alle!
7/2017: Baeldung hat eine gute Zusammenfassung der doppelten Klammerinitialisierung und hält sie für ein Anti-Muster.
12/2017: @Basil Bourque stellt fest, dass man im neuen Java 9 sagen kann:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Das ist mit Sicherheit der richtige Weg. Wenn Sie mit einer früheren Version arbeiten müssen, schauen Sie sich folgende Seiten an Google Collections' ImmutableSet .