我遇到了對我來說毫無意義的奇怪行爲。下面的程序(我試過將其降低到最小的例子)與崩潰NullPointerException
因爲Bar.Y
是null
:Java界面靜態變量未初始化
$ javac *.java
$ java Main
FooEnum.baz()
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:6)
我期待它打印:
FooEnum.baz()
Bar.qux
然而,如果Bar.qux
第一次被訪問(可以通過取消註釋主方法的第一行或通過重新排序以下兩行來完成)程序正確終止。
我懷疑這個問題與Java類的初始化順序有關,但我無法在相關的JLS部分找到任何解釋。
所以,我的問題是:這裏發生了什麼?這是一種錯誤還是我錯過了什麼?
我的JDK版本是1.8.0_111
interface Bar {
// UPD
int barF = InitUtil.initInt("[Bar]");
Bar X = BarEnum.EX;
Bar Y = BarEnum.EY;
default void qux() {
System.out.println("Bar.qux");
}
}
enum BarEnum implements Bar {
EX,
EY;
// UPD
int barEnumF = InitUtil.initInt("[BarEnum]");
}
interface Foo {
Foo A = FooEnum.EA;
Foo B = FooEnum.EB;
// UPD
int fooF = InitUtil.initInt("[Foo]");
double baz();
double baz(Bar result);
}
enum FooEnum implements Foo {
EA,
EB;
// UPD
int fooEnumF = InitUtil.initInt("[FooEnum]");
public double baz() {
System.out.println("FooEnum.baz()");
// UPD this switch can be replaced with `return 42`
switch (this) {
case EA: return 42;
default: return 42;
}
}
public double baz(Bar result) {
switch ((BarEnum) result) {
case EX: return baz();
default: return 42;
}
}
}
public class Main {
public static void main(String[] args) {
// Bar.Y.qux(); // uncomment this line to fix NPE
Foo.A.baz();
Bar.Y.qux();
}
}
// UPD
public class InitUtil {
public static int initInt(String className) {
System.out.println(className);
return 42;
}
}
@Jobin我已經添加了確切的輸出。 – wotopul
@Jobin它並不重要。我正在使用Intellij IDEA和來自終端的普通Java編譯器。 – wotopul