W ukrytych funkcjach Javy najlepsza odpowiedź wspomina o inicjalizacji Double Brace z bardzo kuszącą składnią:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Ten idiom tworzy anonimową klasę wewnętrzną z tylko inicjatorem instancji, który „może używać dowolnych [...] metod w zakresie zawierającym”.
Główne pytanie: czy to jest tak nieefektywne, jak się wydaje? Czy jego stosowanie powinno być ograniczone do jednorazowych inicjalizacji? (I oczywiście popisywanie się!)
Drugie pytanie: nowy zestaw HashSet musi być „tym” używanym w inicjalizatorze instancji ... czy ktoś może rzucić światło na mechanizm?
Trzecie pytanie: czy ten idiom jest zbyt niejasny, aby go używać w kodzie produkcyjnym?
Podsumowanie: Bardzo, bardzo miłe odpowiedzi, dziękuję wszystkim. W przypadku pytania (3) ludzie uważali, że składnia powinna być jasna (chociaż polecam od czasu do czasu komentarz, szczególnie jeśli kod zostanie przekazany programistom, którzy mogą go nie znać).
W przypadku pytania (1) wygenerowany kod powinien działać szybko. Dodatkowe pliki .class powodują zaśmiecenie plików jar i nieznacznie spowalniają uruchamianie programu (dzięki @coobird za pomiar). @Thilo wskazał, że może to mieć wpływ na wyrzucanie elementów bezużytecznych, a koszt pamięci dla dodatkowych klas obciążeń może być czynnikiem w niektórych przypadkach.
Pytanie 2 okazało się dla mnie najbardziej interesujące. Jeśli rozumiem odpowiedzi, w DBI dzieje się tak, że anonimowa klasa wewnętrzna rozszerza klasę obiektu konstruowanego przez nowy operator, a zatem ma wartość „this” odnoszącą się do budowanej instancji. Bardzo schludny.
Ogólnie rzecz biorąc, DBI wydaje mi się intelektualną ciekawością. Coobird i inni podkreślają, że możesz osiągnąć ten sam efekt dzięki Arrays.asList, metodom varargs, kolekcjom Google i proponowanym literałom kolekcji Java 7. Nowsze języki JVM, takie jak Scala, JRuby i Groovy, oferują również zwięzłe oznaczenia do tworzenia list i dobrze współpracują z Javą. Biorąc pod uwagę, że DBI zaśmieca ścieżkę klasy, spowalnia ładowanie klasy i sprawia, że kod jest nieco bardziej niejasny, prawdopodobnie bym się od tego unikał. Planuję jednak przekazać to znajomemu, który właśnie otrzymał SCJP i uwielbia dobre, naturalne potyczki z semantyką Java! ;-) Dziękuję wszystkim!
7/2017: Baeldung ma dobre podsumowanie inicjalizacji podwójnego nawiasu klamrowego i uważa to za anty-wzór.
12/2017: @Basil Bourque zauważa, że w nowej Javie 9 możesz powiedzieć:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
To na pewno droga. Jeśli utkniesz z wcześniejszą wersją, spójrz na ImmutableSet kolekcji Google .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
się, że jestHashSet
, ale niestety jest to anonimowa podklasa.