In generale, non usare blocchi di inizializzazione non statici (e forse evitare anche quelli statici).
Sintassi confusa
Guardando questa domanda, ci sono 3 risposte, ma hai ingannato 4 persone con questa sintassi. Ero uno di loro e scrivo Java da 16 anni! Chiaramente, la sintassi è potenzialmente soggetta a errori! Starei lontano da esso.
Costruttori telescopici
Per cose davvero semplici, puoi usare i costruttori "telescopici" per evitare questa confusione:
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;
}
}
Modello del costruttore
Se hai bisogno di doStuff () alla fine di ogni costruttore o altra sofisticata inizializzazione, forse un modello di generatore sarebbe il migliore. Josh Bloch elenca diversi motivi per cui i costruttori sono una buona idea. I costruttori impiegano un po 'di tempo per scrivere, ma correttamente scritti, sono una gioia da usare.
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();
Cicli di inizializzatori statici
Ho usato per usare statici initializers molto, ma a volte sono imbattuto in loop dove 2 classi dipendevano vicenda statica inizializzatore blocchi chiamati prima della classe potrebbe essere completamente caricato. Ciò ha prodotto un "errore nel caricamento della classe" o un messaggio di errore altrettanto vago. Ho dovuto confrontare i file con l'ultima versione funzionante nota nel controllo del codice sorgente per capire quale fosse il problema. Per niente divertente.
Inizializzazione pigra
Forse gli inizializzatori statici sono buoni per motivi di prestazioni quando funzionano e non sono troppo confusi. Ma in generale, al giorno d'oggi preferisco l' inizializzazione lenta agli inizializzatori statici. È chiaro cosa fanno, non ho ancora incontrato un bug di caricamento di classe con loro e funzionano in più situazioni di inizializzazione rispetto ai blocchi di inizializzatore.
Definizione dei dati
Invece dell'inizializzazione statica per la costruzione di strutture di dati, (confronta con gli esempi nelle altre risposte), ora uso le funzioni di supporto alla definizione dei dati immutabili di Paguro :
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
All'inizio di Java, i blocchi di inizializzazione erano l'unico modo per fare alcune cose, ma ora sono confusi, soggetti a errori e nella maggior parte dei casi sono stati sostituiti da alternative migliori (dettagliate sopra). È interessante conoscere i blocchi di inizializzazione nel caso in cui li vedi nel codice legacy o se si presentano su un test, ma se stavo facendo una revisione del codice e ne avessi visto uno nel nuovo codice, ti chiederei di giustificare perché nessuno dei le alternative sopra erano adatte prima di dare il pollice in alto al codice.