2010-08-17 17 views
97

Quando vengono inizializzati i campi statici? Se non istanzio mai una classe, 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?Quando si verifica l'inizializzazione della classe statica?

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

+0

simili per blocco di inizializzazione statico: http://stackoverflow.com/questions/ 2007666/in-what-order-do-static-initializer-blocks-in-java-run –

risposta

138

inizializzazione statico di una classe normalmente avviene immediatamente prima della prima volta uno dei seguenti eventi:

  • viene creata un'istanza della classe,
  • un metodo statico della classe viene invocato,
  • viene assegnato un campo statico della classe,
  • un campo statico non costante viene utilizzata, o
  • per una classe di primo livello, un'istruzione di asserzione lessicalmente annidato all'interno della classe è eseguito.

Vedere JLS 12.4.1.

È anche possibile forzare una classe per inizializzare (se non è già inizializzato) utilizzando Class.forName(fqn, true, classLoader) o breve modulo Class.forName(fqn)

+0

Cool grazie per le informazioni extra. –

+5

+1 per dare il riferimento JLS – Moshe

+4

Si noti inoltre che il modulo più breve 'Class.forName (className)' impone anche l'inizializzazione perché è equivoco a 'Class.forName (className, true, currentLoader)'. – user113215

1

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

+0

Ci sono modi per fare riferimento a una classe senza inizializzarla. –

11

I campi statici vengono inizializzati durante la "fase" initialization del caricamento della classe (caricamento, collegamento e inizializzazione) che include inizializzatori statici e inizializzazioni dei relativi campi statici. Gli inizializzatori statici vengono eseguiti in un ordine testuale come definito nella classe.

Si consideri 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.

+6

In senso stretto, l'inizializzazione non è una "fase" del caricamento della classe. In effetti, alcune classi * potrebbero * essere caricate ma mai inizializzate se l'applicazione in realtà non le utilizza. –

+0

@Stephen C Hai ragione, l'ho usato per una mancanza di un termine migliore, forse lo citerò. – naikus

+0

@StephenC significa che mentre il caricamento della classe avviene, assegna la memoria a variabili statiche (& metodi) ma quelle variabili statiche non sono inizializzate con i valori forniti nel codice? perché qui sembra quando b-> direCiao() -> a, 'a' è in memoria ma il valore ad esso non è ancora assegnato. –

Problemi correlati