У Прихованих можливості Java верхній відповідь згадує Double Brace ініціалізацію , з дуже привабливим синтаксисом:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Ця ідіома створює анонімний внутрішній клас з просто ініціалізатором екземпляра, який "може використовувати будь-які [...] методи в області, що містить".
Головне питання: чи це неефективно, як це звучить? Чи має бути його використання обмеженим разовими ініціалізаціями? (І звичайно, показуючи!)
Друге питання: Новий HashSet повинен бути "цим", що використовується в ініціалізаторі екземпляра ... чи може хтось пролити світло на механізм?
Третє запитання: чи ця ідіома занадто незрозуміла для використання у виробничому коді?
Резюме: Дуже, дуже приємні відповіді, дякую всім. За запитання (3) люди вважали, що синтаксис повинен бути зрозумілим (хоча я рекомендую епізодичний коментар, особливо якщо ваш код буде переданий розробникам, які можуть не знати його).
За запитання (1), згенерований код повинен швидко працювати. Додаткові файли .class викликають загрозу файлів jar, а також повільний запуск програми (завдяки @coobird для вимірювання цього). @Thilo зазначив, що на збір сміття можуть вплинути, а вартість пам'яті для додатково завантажених класів може бути фактором у деяких випадках.
Питання (2) виявилося для мене найбільш цікавим. Якщо я розумію відповіді, те, що відбувається в DBI, полягає в тому, що анонімний внутрішній клас розширює клас об'єкта, який будується новим оператором, і, отже, має значення "це", що посилається на створений екземпляр. Дуже акуратно.
В цілому DBI вражає мене як щось інтелектуальне цікавість. Coobird та інші зазначають, що ви можете досягти такого ж ефекту за допомогою Arrays.asList, методів varargs, Google Collections та запропонованих літератур Java 7 Collection. Новіші мови JVM, такі як Scala, JRuby та Groovy, також пропонують стислі позначення для створення списків та добре взаємодіють з Java. Зважаючи на те, що DBI захаращує класний шлях, трохи сповільнює завантаження класу і робить код більш незрозумілим, я, мабуть, ухиляюся від нього. Однак я планую навести це на товариша, який щойно здобув свій SCJP і любить добродушні пориви щодо семантики Java! ;-) Дякую всім!
7/2017: Baeldung має хороший підсумок подвійної ініціалізації дужок і вважає це антидіаграмою .
12/2017: @Basil Bourque зазначає, що в новій Java 9 можна сказати:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Це точно шлях. Якщо ви зупинилися на більш ранній версії, подивіться на ImmutableSet Google Collections .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
би бутиHashSet
, але, на жаль, це анонімний підклас.