Este suele ser un tema que se olvida fácilmente o no se tiene en cuenta en la construcción de las clases. En la revisión de código suelo encontrarme con problemas originados por este motivo. Repacemos el orden de ejecución en los bloques de java.
Repasando:
- Los “Init blocks” se ejecutan en el orden que aparecen
- Los “static init blocks” se ejecutan una sola vez cuando la clase es cargada la primera vez.
- Los “Instance init blocks” se ejecutan cada vez que la clase es instanciada, es decir cuando se crea el objecto con “new”
- Los “Instance init blocks” corren después de que el constructor llama a super() *
- Al final se ejecuta el resto del contenido del constructor.
- Recordar que cada constructor tiene un super() por defecto, nuestra JVM lo escribirá aunque nosotros no lo hagamos.
Veamos este ejemplo:
Nota: los init block suelen ubicarse por convención al principio de la clase todos juntos, primero los init block de clase y luego los de instancia, aquí los ubico diferente solo para demostrar el ejemplo.
package gp;
public class Animal {
{
System.out.println("Instance init block Animal - hi");
}
static {
System.out.println("Static init block Animal");
}
public Animal() {
System.out.println("Constructor Animal");
}
{
System.out.println("Instance init block Animal - hello");
}
}
package gp;
public class Dog extends Animal {
{
System.out.println("Instance init block Dog");
}
static {
System.out.println("Static init block Dog");
}
public Dog() {
System.out.println("Constructor Dog");
}
public void breed(String s) {
System.out.println(s);
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.breed("Terrier");
System.out.println("-----------------");
Dog dog2 = new Dog();
dog2.breed("Labrador Retriever");
}
}
¿Cuál será la salida de este código?
Static init block Animal
Static init block Dog
Instance init block Animal - hi
Instance init block Animal - hello
Constructor Animal
Instance init block Dog
Constructor Dog
Terrier
-----------------
Instance init block Animal - hi
Instance init block Animal - hello
Constructor Animal
Instance init block Dog
Constructor Dog
Labrador Retriever
Entonces, resumiento
1-Ejecución de Static Init Block en el orden que que se escribieron en la clase padre e hija (una sola vez cuando la clase es cargada).
2-Ejecución de Instance Init Block de clase padre
3-Ejecución del resto del contenido Constructor de clase padre
4-Ejecución de Instance Init Block de clase hija
6-Ejecución del resto del contenido del Constructor de la clase hija.
7-Alguna otra ejecución
Cualquier comentario, será bienvenido.