In generale, non utilizzare blocchi di inizializzazione non statici (e forse anche evitare quelli statici).
Sintesi confusa
Guardando questa domanda, ci sono 3 risposte, ma hai ingannato 4 persone con questa sintassi. Ero uno di loro e ho scritto Java per 16 anni! Chiaramente, la sintassi è potenzialmente soggetta a errori! Me ne starei lontano.
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 generatore
Se hai bisogno di fareStuff () alla fine di ogni costruttore o altre inizializzazioni sofisticate, forse un modello di builder sarebbe il migliore. Josh Bloch elenca diversi motivi per cui i costruttori sono una buona idea. I costruttori richiedono un po 'di tempo per scrivere, ma se scritti correttamente, 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();
Loop inizializzatori statici
Ho usato molto spesso gli inizializzatori static , ma occasionalmente ho eseguito loop in cui 2 classi dipendevano dai blocchi di inizializzazione statici che venivano chiamati prima che la classe potesse essere caricata completamente. Ciò ha prodotto un messaggio di errore "impossibile caricare la classe" o un messaggio di errore simile. Ho dovuto confrontare i file con l'ultima versione funzionante conosciuta nel controllo del codice sorgente per capire quale fosse il problema. Nessun divertimento.
Inizializzazione pigra
Forse gli inizializzatori statici sono buoni per motivi di prestazioni quando funzionano e non sono troppo confusi. Ma in generale, sto preferendo inizializzazione pigra agli inizializzatori statici in questi giorni. È chiaro che cosa fanno, non ho ancora incontrato bug di caricamento di classe e lavorano in più situazioni di inizializzazione rispetto ai blocchi di inizializzazione.
Definizione dei dati
Invece dell'inizializzazione statica per la costruzione di strutture dati, (confronta con esempi nelle altre risposte), ora utilizzo Funzioni helper di 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 in codice legacy, oppure vengono visualizzati su un test, ma se dovessi fare la revisione del codice e ne ho visto uno in un nuovo codice, ti chiederei di giustificare il motivo per cui nessuno dei le alternative sopra erano adatte prima di dare il pollice al codice.