Quando si verifica l’inizializzazione della class statica?

Quando vengono inizializzati i campi statici? Se non istanzio mai una class, ma accedo a un campo statico, TUTTI sono i blocchi statici e i metodi statici privati ​​usati per istanziare i campi statici privati ​​chiamati (in ordine) in quell’istante?

Cosa succede se chiamo un metodo statico? Esegue anche tutti i blocchi statici? Prima del metodo?

L’inizializzazione statica di una class avviene normalmente immediatamente prima della prima volta che si verifica uno degli eventi seguenti:

  • viene creata un’istanza della class,
  • viene invocato un metodo statico della class,
  • viene assegnato un campo statico della class,
  • viene utilizzato un campo statico non costante o
  • per una class di livello superiore, viene eseguita un’istruzione di asserzione nidificata lessical all’interno della class 1 .

Vedi JLS 12.4.1 .

È anche ansible forzare una class a inizializzare (se non è già stata inizializzata) utilizzando Class.forName(fqn, true, classLoader) o la forma breve Class.forName(fqn)


1 – L’ultimo punto elenco era presente in JLS per Java 6 tramite Java 8, ma apparentemente era un errore nelle specifiche. È stato finalmente corretto in Java 9 JLS: vedi sorgente .

I campi statici vengono inizializzati durante la “fase” di inizializzazione del caricamento della class (caricamento, collegamento e inizializzazione) che include gli inizializzatori statici e le inizializzazioni dei suoi campi statici. Gli inizializzatori statici vengono eseguiti in un ordine testuale come definito nella class.

Considera l’esempio:

 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" } } 

Il Test.b stampa null perché quando il sayHello stato chiamato in ambito statico, la variabile statica a non è stata inizializzata.

Sì, tutti gli inizializzatori statici vengono eseguiti prima di accedere alla class per la prima volta. Se fosse un altro modo, lo definirei un bug.