这是一些简单的代码:
class B {final static int x = C.x;}
class C {final static int x = B.x;}
class A {
static {
System.out.println("A static{}");
new Thread() { public void run() { new B(); }}.start();
new Thread() { public void run() { new C(); }}.start();
}
public static void main(String[] args) {
System.out.println("A main");
System.out.println("B.x: " + B.x);
System.out.println("C.x: " + C.x);
}
}
B.x
并且C.x
是相互定义的。我认为这不应该编译,但确实如此。
当我尝试运行它时,它在 main 中冻结:
$ javac *.java && java A
A static{}
A main
为什么?
然而,它在 gcj 中运行良好:
$ gcj --main=A -o a *.java && ./a
A static{}
A main
B.x: 0
C.x: 0
为什么?
另外,如果我摆脱线程,
class B {final static int x = C.x;}
class C {final static int x = B.x;}
class A {
static {
System.out.println("A static{}");
new B();
new C();
}
public static void main(String[] args) {
System.out.println("A main");
System.out.println("B.x: " + B.x);
System.out.println("C.x: " + C.x);
}
}
它在 java 和 gcj 中都可以正常工作:
$ javac *.java && java A
A static{}
A main
B.x: 0
C.x: 0
$ gcj --main=A -o a *.java && ./a
A static{}
A main
B.x: 0
C.x: 0
并且所有变量都设置为0。为什么?static final
由于变量是并且从未分配到任何地方,这不应该编译失败吗?