domingo, 16 de octubre de 2011

Bloques de Inicialización y Bloques estáticos

Este es de esos temas de los que no sabía nada al respecto pero resulto muy sencillo resulta que existen una par de opciones no muy usadas en java y pueden no llegar a ser muy útiles, pero sí muy interesantes.

Bloques de inicialización

public class Bloques {
       {
             //bloque de inicializacion
       }
       public static void main(String[] args) {

       }
}
Un bloque de inicialización es simplemente un par de llaves({}) colocado dentro de la clase (pero no dentro de un método esos son simples bloques), las instrucciones colocadas allí son ejecutadas inmediatamente después de la llamada a super() de nuestro constructor.
public class Bloques {
       public Bloques(){
             System.out.println("Mi Constructor");
       }
       {
             System.out.println("bloque de inicializacion");
       }
       public static void main(String[] args) {
             new Bloques();
       }

}

Esto tendrá como salida
bloque de inicializacion
Mi Constructor

Bloques estáticos

A diferencia de los bloques de inicialización, los bloques estáticos se ejecutan cuando una clase es cargada, no cuando se crea una instancia, El momento en el que una clase es cargada puede variar por ejemplo cuando hablamos de una o varias clases en un archivo esto quiere decir de inmediato antes incluso de ejecutar la primer instrucción de main.
 public class Bloques {
      
       public Bloques(){
             System.out.println("Mi Constructor");
       }
       static{
             System.out.println("bloque estatico 1");
       }
       {
             System.out.println("bloque de inicializacion");
       }
       static{
             System.out.println("bloque estatico 2");
       }
       public static void main(String[] args) {
             System.out.println("main");
             new Bloques();
       }

}

Produce la salida
bloque estatico 1
bloque estatico 2
main
bloque de inicializacion
Mi Constructor

Cuando la clase está en diferente archivo, la clase se carga cuando es mencionada por primera vez, ya sea creado una instancia o llamando a un atributo o método estático de esta.
Por ejemplo:
public class Bloques {
       static int lalala= 10;
       public Bloques(){
             System.out.println("Mi Constructor");
       }
       static{
             System.out.println("bloque estatico 1");
       }
       {
             System.out.println("bloque de inicializacion");
       }
       static{
             System.out.println("bloque estatico 2");
       }
}

Y en otro archivo:
public static void main(String[] args) {
       System.out.println("main");
       Bloques.lalala++;
}
Se imprimirá en pantalla:
main
bloque estatico 1
bloque estatico 2

Notas Finales
  • Los bloques estáticos se ejecutan una sola vez, los de inicialización cada que se crea un objeto nuevo.
  • Pueden existir múltiples bloques (tanto estáticos como de inicialización) en ese caso se ejecutaran en el orden en que aparecen.
  • Los bloques estáticos no deben hacer mención de métodos o atributos de la clase no estaticos.

6 comentarios:

  1. excelente explicacion, mejor que el manual oficial de oracle

    ResponderEliminar
  2. Hola
    duda sobre este punto
    `
    Los bloques estáticos no deben hacer mención de métodos o atributos de la clase no estaticos.
    ´
    Podría usar un bloque static para crear la instancia de un singleton?

    Muchas Gracias

    ResponderEliminar
    Respuestas
    1. Por supuesto. De hecho la instancia de un singleton corresponde a una variable estática o de clase, que es lo mismo, y, por lo tanto, debe ser inicializada dentro de un bloque de inicialización estático.

      Eliminar