Dalam Fitur Tersembunyi di Jawa , jawaban teratas menyebutkan Inisialisasi Brace Ganda , dengan sintaks yang sangat menarik:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Ungkapan ini membuat kelas dalam anonim hanya dengan inisialisasi instance di dalamnya, yang "dapat menggunakan metode [...] dalam lingkup yang berisi".
Pertanyaan utama: Apakah ini tidak efisien karena kedengarannya? Haruskah penggunaannya terbatas pada inisialisasi sekali saja? (Dan tentu saja pamer!)
Pertanyaan kedua: HashSet baru harus menjadi "ini" yang digunakan dalam initializer instance ... adakah yang bisa menjelaskan mekanisme ini?
Pertanyaan ketiga: Apakah idiom ini terlalu tidak jelas untuk digunakan dalam kode produksi?
Ringkasan: Jawaban yang sangat, sangat bagus, terima kasih semuanya. Pada pertanyaan (3), orang-orang merasa sintaksinya harus jelas (walaupun saya akan merekomendasikan komentar sesekali, terutama jika kode Anda akan diteruskan ke pengembang yang mungkin tidak akrab dengannya).
Pada pertanyaan (1), kode yang dihasilkan harus berjalan dengan cepat. File .class tambahan memang menyebabkan kekacauan file jar, dan sedikit memperlambat startup program (terima kasih kepada @coobird untuk mengukurnya). @ Thilo menunjukkan bahwa pengumpulan sampah dapat terpengaruh, dan biaya memori untuk kelas-kelas tambahan mungkin menjadi faktor dalam beberapa kasus.
Pertanyaan (2) ternyata paling menarik bagi saya. Jika saya mengerti jawabannya, apa yang terjadi di DBI adalah bahwa kelas dalam anonim memperluas kelas objek yang sedang dibangun oleh operator baru, dan karenanya memiliki nilai "ini" yang merujuk pada instance yang sedang dibangun. Sangat rapi.
Secara keseluruhan, DBI menganggap saya sebagai suatu keingintahuan intelektual. Coobird dan yang lainnya menunjukkan bahwa Anda dapat mencapai efek yang sama dengan Arrays.asList, metode varargs, Google Collections, dan literal Java 7 Collection yang diusulkan. Bahasa JVM yang lebih baru seperti Scala, JRuby, dan Groovy juga menawarkan notasi ringkas untuk konstruksi daftar, dan beroperasi dengan baik dengan Java. Mengingat bahwa DBI mengacaukan classpath, memperlambat memuat kelas sedikit, dan membuat kode sedikit lebih jelas, saya mungkin akan menghindarinya. Namun, saya berencana untuk menceritakan hal ini pada seorang teman yang baru saja mendapatkan SCJP-nya dan suka sekali dorongan sifat alami tentang semantik Jawa! ;-) Terimakasih semuanya!
7/2017: Baeldung memiliki ringkasan yang bagus untuk inisialisasi penjepit ganda dan menganggapnya sebagai anti-pola.
12/2017: @Basil Bourque mencatat bahwa di Java 9 yang baru Anda dapat mengatakan:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Itu pasti cara untuk pergi. Jika Anda terjebak dengan versi yang lebih lama, lihat ImmutableSet dari Google Collections .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
menjadiHashSet
, tetapi sayangnya itu adalah subkelas anonim.