2009-09-04 12 views
0

次のコードがNullpointerExceptionsを投げつづけているのは絶対的にわかりません。私はこれを理解したりデバッグすることができませんでした。(より大きいクラスの下位コードは削除されました)..."this"リファレンスをJavaコンストラクタでArrayに追加できません

コードは "Enum Pattern"に基づいており、すべての "Constants"クラスに含まれている(私はこれのためにリフレクションを使用しますが一覧/地図を使用している可能性がはるかに簡単です...)

public class Country { 

     public static final Country SWITZERLAND = new Country("SWITZERLAND"); 

     private static ArrayList<Country> countries = new ArrayList<Country>(); 

     private Country(String constname) {  
      //constname is currently not used (I will use it for a Key in a Map) 
      System.out.println(constname); 
      System.out.println("Ref debug:"+this); 

      //Ad this to the Countries 
      Country.countries.add(this); 
     } 
    } 

ヘルプは非常に高く評価されるだろう。私はここで何が欠けていますか?

+1

これはゲラット学習でした:それを要約すると、静的イニシャライザの順序は関係あります!!! お返事いただきありがとうございます。 – jan

+0

自己登録コンストラクタは実際には良い考えではありません。 –

答えて

4

は(JLS section 8.7で指定されるように)テキストの順序で実行されています。あなたが最初ArrayListを入れた場合、それは動作します:明確に指定された順序を維持するために静的コンストラクタを使用しての

public class Country {  
    private static ArrayList<Country> countries = new ArrayList<Country>(); 

    public static final Country SWITZERLAND = new Country("SWITZERLAND"); 

... 

コンラートの提案がが良いものです。

Javaを「1.5より前」使用していますか?そうでない場合は、ストレート列挙型を使用してください。

+0

+1 ...私は実際にはJavaに流暢ではないので、初期化の順序についてはわかりませんでした。 Jonはテキストであると言っているので、この解決策は 'static'ブロック(IMHO)より優れています。 –

5

SWITZERLANDは、静的であること、潜在的にもstaticである、countriesが初期化されます。したがって、countriesは、SWITZERLANDのコンストラクタコールではまだnullです。

staticブロック使用し、初期の明確に定義された順序を強制する:、コンラッドが言ったことに静的変数初期化子を展開する

public class Country { 

    public static final Country SWITZERLAND; 

    private static ArrayList<Country> countries; 

    static { 
     countries = new ArrayList<Country>(); 
     SWITZERLAND = new Country("SWITZERLAND"); 
    } 
} 
+0

初期化の順序は常に明確です。これはテキスト順に実行されます。 +1は静的な初期化ブロックです。このようにして、読者の実行順序がより明確になります。 –

1

SWITZERLANDを初期化する '国'コンストラクタコールcountriesの初期化の前に静的フィールドが発生します。静的フィールド定義の順序を変更すると、よりうまくいくでしょう。

-1

私はコードがうまくいくかもしれないと思います。クラスのコンストラクタはパブリックメソッドをプライベートではなく定義する必要があります。

国(文字列のconstname形式){
constname形式は現在使用されていません// するSystem.out.println(constname形式)(Iは、マップ内のキーのためにそれを使用します)。 System.out.println( "Refデバッグ:" + this);

 //Ad this to the Countries 
     Country.countries.add(this); 
    } 
+0

コンストラクタの可視性は問題とは関係ありません。 – mikej

4

私は、これはジョンがそれを与えた一遍の言及以上に値すると思うので:

「タイプセーフな列挙型のパターン」は廃止されました!

古くなったJavaバージョン(以前はSunでサポートされていない1.5以上)を使用しない限り、Javaのreal Enumsを使用する必要があります。これにより、多くの作業と手間が省けます型保証された列挙型は非常に難しいです)、ちょうどすべて素晴らしいです。

関連する問題