Bloque static de Java: inicializadores estáticos y otros usos

Los bloques estáticos en Java son una herramienta muy útil para ejecutar código una única vez cuando una clase se carga en memoria. Estos bloques comienzan con la palabra clave static seguida de un par de llaves, dentro de las cuales colocamos el código que queremos que se ejecute en ese momento. La idea principal es que este código se ejecute antes que cualquier otro método, ya sea estático o no, incluyendo el método main o los constructores.

Por ejemplo, si dentro de un bloque estático ponemos un println que diga este es el static de main, y también tenemos un método main con otro println, al ejecutar la clase veremos primero el mensaje del bloque estático y luego el del método main. Esto sucede porque para ejecutar cualquier método de una clase, primero la clase debe cargarse en memoria, y en ese momento se ejecuta el bloque estático.

Un aspecto importante a tener en cuenta es que dentro de un bloque estático no podemos acceder a atributos o métodos que no sean estáticos. Esto se debe a que el bloque estático no está asociado a ninguna instancia concreta de la clase, sino a la clase en sí misma. Por lo tanto, no podemos modificar ni leer atributos de instancia ni llamar a métodos no estáticos desde el bloque estático. Solo podemos usar atributos y métodos estáticos.

Además, el orden en que declaramos los elementos dentro de la clase importa cuando trabajamos con bloques estáticos. Si intentamos usar un atributo estático dentro del bloque estático que aún no ha sido declarado, el código no compilará. Por eso, siempre debemos declarar primero los atributos estáticos y luego el bloque estático que los utiliza.

Un detalle que a veces puede generar confusión es que el bloque estático no se ejecuta simplemente porque el programa se haya iniciado o porque la máquina virtual de Java esté corriendo. El bloque estático solo se ejecuta la primera vez que se utiliza la clase, ya sea porque llamamos a un método estático, accedemos a un atributo estático o creamos una instancia de la clase. Hasta ese momento, el bloque estático permanece sin ejecutarse.

Para ilustrar esto, imaginemos una clase con un bloque estático que imprime un mensaje, un constructor que también imprime otro mensaje, y un método estático que hace lo mismo. Si ejecutamos el programa sin usar esta clase, no veremos ningún mensaje. Pero si dentro del método main llamamos a ese método estático o creamos una instancia de la clase, entonces veremos primero el mensaje del bloque estático y después el del método o constructor. Y si volvemos a llamar al método estático, el bloque estático no se ejecutará de nuevo, porque solo se ejecuta una vez, la primera vez que se carga la clase.

Este comportamiento nos permite usar los bloques estáticos para inicializaciones globales que solo deben hacerse una vez, como configurar variables estáticas o preparar recursos compartidos. Sin embargo, no debemos pensar en ellos como mecanismos para crear clases dinámicas o cargadores personalizados, ya que su función está limitada a esa inicialización única.

Para resumir el uso básico de un bloque estático, podemos verlo en este ejemplo:

public class Ejemplo {
    static int contador = 0;

    static {
        System.out.println("Bloque estático ejecutado");
        contador = 10;
    }

    public static void main(String[] args) {
        System.out.println("Valor de contador: " + contador);
    }
}

Al ejecutar esta clase, primero se imprimirá Bloque estático ejecutado cuando la clase se cargue, y luego Valor de contador: 10 desde el método main. Si no usamos la clase, el bloque estático no se ejecutará.

En definitiva, los bloques estáticos son una forma elegante y eficiente de realizar inicializaciones globales en Java, siempre que tengamos en cuenta sus limitaciones y el momento exacto en que se ejecutan.

Lista de reproducción
  1. 1
    ¿Cómo funciona Comparator en Java?
    10 minutos
  2. 2
    ¿Para qué sirve Override?
    4 minutos
  3. 3
    Cómo usar la clase Properties en Java
    14 minutos
  4. 4
    Interfaces funcionales y funciones flecha
    8 minutos
  5. 5
    Bloque static de Java: inicializadores estáticos y otros usos
    7 minutos
  6. 6
    import static, ¿para qué sirve?
    3 minutos
  7. 7
    Uso de Optional en Java
    10 minutos
  8. 8
    Introducción al Scanner de Java
    11 minutos
  9. 9
    ¿Para qué sirve el modificador static de Java?
    6 minutos
  10. 10
    Funciones variádicas en Java
    6 minutos
  11. 11
    Inner classes en Java
    8 minutos
  12. 12
    var en Java: una introducción para gente nueva
    7 minutos
  13. 13
    Switch expressions en Java
    10 minutos
  14. 14
    Java: del instanceof al Pattern Matching
    7 minutos
  15. 15
    Sealed classes en Java
    8 minutos
  16. 16
    Getters y setters o atributos públicos en Java, ¿qué es mejor?
    9 minutos
  17. 17
    El String[] args del método main de Java
    8 minutos
  18. 18
    Introducción a clases anónimas en Java
    6 minutos
  19. 19
    Introducción a enum en Java
    6 minutos