¿Cuándo ocurre la inicialización de la clase estática?

¿Cuándo se inicializan los campos estáticos? Si nunca instanciar una clase, pero tengo acceso a un campo estático, ¿TODOS los bloques estáticos y los métodos estáticos privados se usan para crear instancias de campos estáticos privados llamados (en orden) en ese instante?

¿Qué sucede si llamo a un método estático? ¿También ejecuta todos los bloques estáticos? Antes del método?

La inicialización estática de una clase normalmente ocurre inmediatamente antes de la primera vez que ocurre uno de los siguientes eventos:

  • se crea una instancia de la clase,
  • se invoca un método estático de la clase,
  • se asigna un campo estático de la clase,
  • se usa un campo estático no constante, o
  • para una clase de nivel superior, se ejecuta una statement de afirmación léxicamente anidada dentro de la clase 1 .

Ver JLS 12.4.1 .

También es posible forzar a una clase a inicializarse (si aún no se ha inicializado) utilizando Class.forName(fqn, true, classLoader) o la forma abreviada Class.forName(fqn)


1 – El punto final estaba presente en el JLS para Java 6 a través de Java 8, pero aparentemente fue un error en la especificación. Finalmente se corrigió en Java 9 JLS: ver fuente .

Los campos estáticos se inicializan durante la “fase” de inicialización de la carga de clase (carga, enlace e inicialización) que incluye inicializadores estáticos e inicializaciones de sus campos estáticos. Los inicializadores estáticos se ejecutan en un orden textual como se define en la clase.

Considera el ejemplo:

 public class Test { static String sayHello() { return a; } static String b = sayHello(); // a static method is called to assign value to b. // but its a has not been initialized yet. static String a = "hello"; static String c = sayHello(); // assignes "hello" to variable c public static void main(String[] arg) throws Throwable { System.out.println(Test.b); // prints null System.out.println(Test.sayHello()); // prints "hello" } } 

Test.b imprime null porque cuando se llamó a sayHello en el ámbito estático, la variable estática a no se inicializó.

Sí, todos los inicializadores estáticos se ejecutan antes de acceder a la clase por primera vez. Si fuera de otra manera, lo llamaría un error.