2009-07-15 8 views
9

Ok quindi questa è una domanda newbie su java, ma non riesco a capirlo.Spiegazione di come il classloader carica le variabili statiche

ho il seguente codice all'interno della mia classe

private static final String [] LIST_CODE = gerarListCode(); 
private static final int [][] LIST_INTEGER = new int [][] { 
     {947,947}, {110,103}, 
     {947,958}, {110,120}, 
     {947,954}, {103,107}, 
     {947,967}, {110,99,104}}; 

private static String [] gerarListCode() 
    { 
     String [] listCode = new String [LIST_INTEGER.length]; 

     for (int i=0 ; i<LIST_INTEGER.length ; i++) 
     { 
      //do some stuff  
     } 

     return listaUnicode; 
    } 

Questo codice mi sta dando un'eccezione di inizializzazione a causa di un NullPointerException nella riga seguente

String [] listCode = new String [LIST_INTEGER.length]; 

Sembra la LIST_INTEGER variabile è nulla in quel tempo.

Qualcuno può spiegare perché? il processo classloader è lineare, in altre parole, invoca il metodo prima di caricare completamente tutte le altre variabili?

+1

spostare la dichiarazione di LIST_INTEGER alla riga prima di LIST_CODE – Ron

risposta

11

Sì, in breve, è lineare.

"Cosa fa il compilatore effettivamente è produrre internamente una singola classe routine di inizializzazione che unisce tutti gli inizializzatori variabili statiche e tutti del inizializzatore statico blocchi di codice, nell'ordine in cui essi appaiono nella dichiarazione di classe Questa procedura di inizializzazione singola viene eseguita automaticamente, una volta sola, , quando viene caricata la classe . "

Tratto da Java in poche parole.

http://www.developer.com/java/other/article.php/2238491

È necessario definire le variabili e poi li inizializza in un blocco intitializer statica nell'ordine corretto, o si potrebbe scambiare l'ordine delle istruzioni nel seguente modo:

private static final int [][] LIST_INTEGER = new int [][] { {947,947}, {110,103}, 
     {947,958}, {110,120}, 
     {947,954}, {103,107}, 
     {947,967}, {110,99,104}}; 

private static final String [] LIST_CODE = gerarListCode(); 
+0

In senso stretto, non è quando la classe viene caricata, ma in seguito, quando viene inizializzata. –

4

La JVM, infatti, inizializzerà i campi statici nell'ordine in cui li incontra.

I campi statici di una classe vengono inizializzati quando la classe viene rilevata per la prima volta dalla JVM. Secondo Java Puzzlers, il puzzle 49 (che continua a fare riferimento a JLS 4.12.5), i campi statici vengono prima impostati sui loro valori predefiniti. Le variabili oggetto sono impostate su null, int s sono impostate su 0, ecc. Dopodiché, i loro inizializzatori vengono eseguiti in ordine di apparizione.

Quindi, nel vostro esempio, LIST_CODE e LIST_INTEGER vengono prima impostati su null. Quindi, LIST_CODE viene inizializzato chiamando gerarListCode(). LIST_INTEGER è ancora null quando viene eseguito quel metodo. Solo dopo questo, LIST_INTEGER viene inizializzato con il valore letterale specificato nell'esempio.

+0

Non ha nulla a che fare con il caricatore di classi. È implementato da javac creando l'inizializzatore statico in ordine di sorgente. –

+0

Grazie per la cattura, Tom! Ho aggiornato la mia risposta. – jqno