В разделе « Скрытые возможности Java» в верхнем ответе упоминается инициализация двойной скобки с очень заманчивым синтаксисом:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Эта идиома создает анонимный внутренний класс с инициализатором экземпляра, который «может использовать любые [...] методы в содержащей области».
Главный вопрос: это так же неэффективно, как кажется? Следует ли ограничить его использование одноразовыми инициализациями? (И конечно же хвастаться!)
Второй вопрос: новый HashSet должен быть «этим», используемым в инициализаторе экземпляра ... может кто-нибудь пролить свет на механизм?
Третий вопрос: слишком ли неясна эта идиома для использования в рабочем коде?
Резюме: Очень, очень хорошие ответы, спасибо всем. На вопрос (3) люди считали, что синтаксис должен быть ясным (хотя я бы рекомендовал время от времени комментировать, особенно если ваш код будет передаваться разработчикам, которые могут быть не знакомы с ним).
На вопрос (1) сгенерированный код должен работать быстро. Дополнительные файлы .class вызывают беспорядок в jar-файле и слегка замедляют запуск программы (спасибо @coobird за это). @Thilo отметил, что это может повлиять на сборку мусора, и стоимость памяти для дополнительных загруженных классов может быть фактором в некоторых случаях.
Вопрос (2) оказался наиболее интересным для меня. Если я понимаю ответы, то в DBI происходит то, что анонимный внутренний класс расширяет класс объекта, создаваемого оператором new, и, следовательно, имеет значение «this», ссылающееся на создаваемый экземпляр. Очень аккуратный.
В целом, 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
, но , увы , это анонимный подкласс.