La sintassi di inizializzazione dei campi dell'istanza è un blocco di codice speciale racchiuso tra parentesi graffe all'interno di una classe, ma al di fuori di metodi e costruttori. Questo blocco è chiamato instance initializer block. Viene eseguito ogni volta che viene creato un nuovo oggetto della classe, immediatamente dopo la chiamata al costruttore della classe genitore e prima dell'esecuzione del codice del costruttore della classe corrente.
public class Example { { // Instance initializer block System.out.println("Inizializzazione dell'istanza"); } private int x; public Example(int x) { this.x = x; System.out.println("Costruttore"); } }
L'instance initializer è utile per:
Cosa succede se ci sono sia l'instance initializer che il costruttore nella classe? In quale ordine vengono eseguiti?
Risposta: Prima viene eseguito l'instance initializer, poi il codice del costruttore. Se nella classe ci sono più blocchi di instance initializer, vengono eseguiti nell'ordine in cui sono stati descritti.
Esempio:
public class Demo { { System.out.println("Instance initializer 1"); } public Demo() { System.out.println("Costruttore"); } { System.out.println("Instance initializer 2"); } } // Output quando new Demo(): // Instance initializer 1 // Instance initializer 2 // Costruttore
Storia
In un progetto, un sviluppatore ha posizionato la logica nell'instance initializer anziché in un metodo o costruttore. Durante l'ereditarietà della classe e la sovrascrittura del costruttore, l'instance initializer è comunque stato eseguito, portando a un ordine di inizializzazione inaspettato e a errori nella logica di business.
Storia
In un altro progetto, l'instance initializer accedeva ai campi della classe che erano stati inizializzati più in basso nel codice. Si è scoperto che le variabili non erano ancora state inizializzate, e si è verificato un NullPointerException durante la creazione dell'oggetto.
Storia
Il team ha aggiunto nell'instance initializer un'operazione relativa a risorse esterne (DB). Di conseguenza, ogni chiamata al costruttore stabiliva una connessione al DB, sovraccaricando il sistema durante la creazione di oggetti in batch.