La sintaxis de inicialización de campos de instancia es un bloque de código especial, encerrado en llaves dentro de una clase, pero fuera de los métodos y constructores. Este bloque se llama instance initializer block. Se ejecuta cada vez que se crea un nuevo objeto de la clase, justo después de llamar al constructor de la clase padre y antes de ejecutar el código del constructor de la clase actual.
public class Example { { // Bloque de inicialización de instancia System.out.println("Inicialización de instancia"); } private int x; public Example(int x) { this.x = x; System.out.println("Constructor"); } }
El instance initializer es útil para:
¿Qué pasará si en la clase existen tanto un instance initializer como un constructor? ¿En qué orden se ejecutan?
Respuesta: Primero se ejecuta el instance initializer, luego el código del constructor. Si en la clase hay varios bloques de instance initializer, se ejecutan en el orden en que se describen.
Ejemplo:
public class Demo { { System.out.println("Instance initializer 1"); } public Demo() { System.out.println("Constructor"); } { System.out.println("Instance initializer 2"); } } // Salida al crear new Demo(): // Instance initializer 1 // Instance initializer 2 // Constructor
Historia
En un proyecto, un desarrollador colocó la lógica en un instance initializer en lugar de un método o constructor. Al heredar la clase y sobrescribir el constructor, el instance initializer aún se ejecutó, lo que llevó a un orden de inicialización inesperado y errores en la lógica de negocio.
Historia
En otro proyecto, el instance initializer accedió a los campos de la clase que fueron inicializados más abajo en el código. Resultó que las variables aún no estaban inicializadas, y se produjo un NullPointerException al crear el objeto.
Historia
El equipo agregó en el instance initializer una operación relacionada con recursos externos (BD). Debido a esto, cada llamada al constructor establecía una conexión a la BD, lo que sobrecargó el sistema al crear objetos en lote.