私には意味をなさない奇妙な動作が発生しています。私は印刷にそれを期待Javaインターフェイスの静的変数が初期化されていません
$ javac *.java
$ java Main
FooEnum.baz()
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:6)
:NullPointerException
null
あるBar.Y
ため、次のプログラムがでクラッシュ(私は、最小限の例にそれを軽減しようとした)Bar.qux
に最初にアクセスした場合は
FooEnum.baz()
Bar.qux
(メインメソッドの最初の行をコメント解除するか、または次の2行を並べ替えることによって実行できます)、プログラムは正しく終了します。
この問題は、Javaクラスの初期化の順序と関係していると思われますが、関連するJLSセクションで説明が見つかりませんでした。
私の質問は、ここで何が起こっているのですか?これは何らかのバグですか、何か不足していますか?
私のJDKのバージョンあなたはFoo
インターフェイスの初期化とFooEnum
列挙型の初期化の間に循環依存を持つ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
@ジョビンそれは本当に問題ではありません。私はIntellij IDEAとターミナルからプレーンJavaコンパイラの両方を使用しています。 – wotopul