Secara umum, jangan gunakan blok penginisialisasi non-statis (dan mungkin hindari yang statis juga).
Sintaks yang membingungkan
Melihat pertanyaan ini, ada 3 jawaban, namun Anda membodohi 4 orang dengan sintaks ini. Saya adalah salah satu dari mereka dan saya telah menulis Java selama 16 tahun! Jelas, sintaksnya berpotensi rawan kesalahan! Aku akan menjauh darinya.
Konstruktor Telescoping
Untuk hal-hal yang sangat sederhana, Anda dapat menggunakan konstruktor "telescoping" untuk menghindari kebingungan ini:
public class Test {
private String something;
// Default constructor does some things
public Test() { doStuff(); }
// Other constructors call the default constructor
public Test(String s) {
this(); // Call default constructor
something = s;
}
}
Pola Pembangun
Jika Anda perlu melakukanStuff () di akhir setiap konstruktor atau inisialisasi canggih lainnya, mungkin pola pembangun akan menjadi yang terbaik. Josh Bloch mendaftar beberapa alasan mengapa pembangun adalah ide yang bagus. Pembangun membutuhkan sedikit waktu untuk menulis, tetapi ditulis dengan benar, mereka senang digunakan.
public class Test {
// Value can be final (immutable)
private final String something;
// Private constructor.
private Test(String s) { something = s; }
// Static method to get a builder
public static Builder builder() { return new Builder(); }
// builder class accumulates values until a valid Test object can be created.
private static class Builder {
private String tempSomething;
public Builder something(String s) {
tempSomething = s;
return this;
}
// This is our factory method for a Test class.
public Test build() {
Test t = new Test(tempSomething);
// Here we do your extra initialization after the
// Test class has been created.
doStuff();
// Return a valid, potentially immutable Test object.
return t;
}
}
}
// Now you can call:
Test t = Test.builder()
.setString("Utini!")
.build();
Initializer Loop Statis
Saya sering menggunakan penginisialisasi statis banyak, tetapi kadang-kadang berlari ke loop di mana 2 kelas tergantung pada blok penginisialisasi statis masing-masing dipanggil sebelum kelas bisa dimuat penuh. Ini menghasilkan "gagal memuat kelas" atau pesan kesalahan yang juga tidak jelas. Saya harus membandingkan file dengan versi kerja terakhir yang diketahui dalam kontrol sumber untuk mencari tahu apa masalahnya. Tidak menyenangkan sama sekali.
Inisialisasi Malas
Mungkin inisialisasi statis baik untuk alasan kinerja ketika mereka bekerja dan tidak terlalu membingungkan. Tetapi secara umum, saya lebih suka inisialisasi malas daripada inisialisasi statis hari ini. Sudah jelas apa yang mereka lakukan, saya belum menemukan bug pemuatan kelas dengan mereka, dan mereka bekerja dalam lebih banyak situasi inisialisasi daripada blok inisialisasi.
Definisi Data
Alih-alih inisialisasi statis untuk membangun struktur data, (bandingkan dengan contoh dalam jawaban lain), saya sekarang menggunakan fungsi pembantu definisi data Paguro yang tidak berubah :
private ImMap<String,String> days =
map(tup("mon", "monday"),
tup("tue", "tuesday"),
tup("wed", "wednesday"),
tup("thu", "thursday"),
tup("fri", "friday"),
tup("sat", "saturday"),
tup("sun", "sunday"));
Conculsion
Pada awal Java, blok initializer adalah satu-satunya cara untuk melakukan beberapa hal, tetapi sekarang mereka membingungkan, rentan kesalahan, dan dalam banyak kasus telah digantikan oleh alternatif yang lebih baik (dirinci di atas). Sangat menarik untuk mengetahui tentang blok penginisialisasi jika Anda melihatnya dalam kode warisan, atau mereka muncul pada suatu pengujian, tetapi jika saya sedang melakukan tinjauan kode dan saya melihatnya dalam kode baru, saya akan meminta Anda untuk membenarkan mengapa tidak ada alternatif di atas cocok sebelum memberikan kode Anda jempol.