2009-07-15 9 views
9

これはJava上の初心者の質問ですが、私はその頭の中で頭を上げるように見えません。クラスローダーが静的変数をロードする方法の説明

私が原因次の行

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

内のNullPointerExceptionに私のクラス

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

このコードは、私の初期化例外を与えているの内側に次のコードを持っているが、変数LIST_INTEGERが、その時にnullであるようです時間。

誰かが理由を説明できますか?つまり、他のすべての変数を完全にロードする前にメソッドを呼び出しますか?

+1

LIST_CODEより前の行にはLIST_INTEGERがあります – Ron

答えて

11

はい、要するに、線形です。

「何コンパイラが実際には内部的に、彼らが表示され という順番で、 すべての静的変数初期化子 とコードの静的初期化子 ブロックの全てを兼ね備えた単一のクラス 初期化ルーチンを生成 にありますこの 単一の初期化プロシージャは、 クラスが最初にロードされたときに、 を自動的に1回だけ実行します。

Javaから一言で言えば、

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

あなたは、変数を定義して、正しい順序で静的intitializerブロックでそれらを初期化するか、次のように文の順序を入れ替えることができなければならない:

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

厳密に言えば、クラスがロードされたときではなく、後で初期化されるときです。 –

4

JVMは実際には、静的フィールドを検出した順番で初期化します。

クラスの静的フィールドは、クラスがJVMで初めて検出されたときに初期化されます。パズル49(を参照しています)によれば、静的フィールドは最初にデフォルト値に設定されます。オブジェクト変数はnullに設定され、intは0に設定されます。その後、初期化子は外観順に実行されます。

したがって、あなたの例では、LIST_CODELIST_INTEGERは、最初にnullに設定されています。次にLIST_CODEgerarListCode()を呼び出して初期化されます。 LIST_INTEGERは、そのメソッドが実行されるときにはまだnullです。その後、LIST_INTEGERは、あなたの例で与えたリテラル値で初期化されます。

+0

クラスローダーとは関係ありません。これは、ソースの順に静的な初期化子を作成するjavacによって実装されています。 –

+0

キャッチをありがとう、トム!私は私の答えを更新しました。 – jqno