I'm experiencing strange behavior that does not make sense to me. The following program (I've tried to reduce it to minimal example) crashes with NullPointerException
because Bar.Y
is null
:
$ javac *.java
$ java Main
FooEnum.baz()
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:6)
I expect it to print:
FooEnum.baz()
Bar.qux
However if Bar.qux
is accessed first (it could be done by either uncommenting the first line of the main method or by reordering the following two lines) the program terminates correctly.
I suspect this issue has something to do with Java class initialization order but I was unable to find any explanation in relevant JLS sections.
So, my question is: what is going on here? Is this some kind of bug or am I missing something?
My JDK version is 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;
}
}