私はSetクラスを持っています(これはJ2MEなので、私は標準APIへのアクセスが制限されています;クラスとサブクラスで一定のセットを作成するために、私はsetクラスを使用しています。これは、このような外観です...静的イニシャライザをJavaで実行する順序を保証できますか?
class ParentClass
{
protected final static Set THE_SET = new Set() {{
add("one");
add("two");
add("three");
}};
}
class SubClass extends ParentClass
{
protected final static Set THE_SET = new Set() {{
add("four");
add("five");
add("six");
union(ParentClass.THE_SET); /* [1] */
}};
}
[1]の行を除いて、すべてがうまく見えますが、nullポインタ例外が発生します。おそらく、これは、サブクラスの静的な初期化子が親クラスの前に実行されていることを意味します。これは、instatiatedサブクラスで実行する前に、最初に新しいインポートで静的ブロックを実行すると思っていたので、私を驚かせました。
私はこの仮定の通りですか?この動作を制御または回避する方法はありますか?
更新:
物事はさえ見知らぬ人です。私は、これは代わりに(「新しいParentClass()」行に注意してください)試してみました:
class ParentClass
{
public ParentClass()
{
System.out.println(THE_SET);
}
protected final static Set THE_SET = new Set() {{
add("one");
add("two");
add("three");
}};
}
class SubClass extends ParentClass
{
protected final static Set THE_SET = new Set() {{
System.out.println("a");
new ParentClass();
System.out.println("b");
add("four");
System.out.println("c");
add("five");
System.out.println("d");
add("six");
System.out.println("e");
union(ParentClass.THE_SET); /* [1] */
System.out.println("f");
}};
}
、出力は奇妙です:
a
["one", "two", "three"]
b
c
d
e
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
だからParentClassが初期化されますが、サブクラスがアクセス権を持っていませんその静的なイニシャライザ内にあります。
それも同じことです。 – izb
私はエリヤが正しいと思う。これは初期化順序の問題ではなく、むしろ一種の名前の衝突です。 – boutta
実際のコードでは、実際にはA <-B <-Cの3つのクラスがあります。興味深いことに、各クラスに独自のセット名を与えるとCに例外が移りますが、問題は解決しません。これは単に注文が実際には予測できないことを意味します。 – izb