In Java i blocchi di inizializzazione (init-block) sono blocchi di codice speciali che vengono eseguiti durante la creazione di un'istanza di un oggetto della classe, ma prima della chiamata al costruttore. Esistono due tipi:
public class Example { static { System.out.println("Blocco statico"); } { System.out.println("Blocco dell'istanza"); } public Example() { System.out.println("Costruttore"); } }
Quando viene creato un nuovo oggetto verrà stampato:
Blocco statico
Blocco dell'istanza
Costruttore
Usare i blocchi di inizializzazione ha senso quando è necessaria una logica comune per tutti i costruttori, oppure un'inizializzazione complessa che non rientra nell'inizializzazione delle variabili. Ma nella maggior parte dei casi si preferisce utilizzare i costruttori.
Domanda: In quale ordine vengono inizializzati i campi, i blocchi statici, i blocchi di istanza e i costruttori durante la creazione di un oggetto?
Risposta:
Storia
In un grande progetto è sorto un problema con l'inizializzazione: uno degli sviluppatori stava trasferendo la logica comune dal costruttore al blocco init, senza tenere conto dell'ordine delle chiamate. Questo ha portato a situazioni in cui alcuni campi non erano correttamente inizializzati prima che la logica fosse eseguita, causando un NullPointerException durante la creazione dell'oggetto.
Storia
Il riutilizzo di un grande blocco init in una classe astratta, da cui venivano ereditate altre classi, ha portato al fatto che le sottoclassi non sovrascrivevano correttamente l'ordine di inizializzazione. Questo ha causato comportamenti imprevisti durante l'ereditarietà e bug legati all'ordine di chiamata dei blocchi init e dei costruttori.
Storia
Uno sviluppatore ha supposto che i campi statici potessero essere reinizializzati ad ogni nuova creazione di oggetto e ha aggiunto una logica di pulizia delle risorse al blocco statico. Questo ha portato al fatto che le risorse venivano pulite solo una volta durante il caricamento della classe, e tutta la successiva gestione della memoria è "fallita". Poiché il blocco statico viene eseguito solo una volta, ciò ha portato a perdite di memoria e gestione errata delle risorse.