我有一个 Set 类(这是 J2ME,所以我对标准 API 的访问权限有限;只是为了解释我明显的轮子改造)。我正在使用我的集合类在类和子类中创建常量集合。有点像这样...
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] 处的行导致空指针异常。大概这意味着子类中的静态初始化器在父类之前运行。这让我感到惊讶,因为我认为它会先在任何新导入中运行静态块,然后再在实例化子类中运行任何块。
我的这个假设是对的吗?有没有办法控制或解决这种行为?
更新:
事情就更奇怪了。我尝试了这个(注意'new 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 已初始化,但子类在其静态初始化程序中无权访问它。