Here is some simple code:
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
and C.x
are defined in terms of each other. I thought this should not compile but it does.
It freezes in main when I try to run it:
$ javac *.java && java A
A static{}
A main
Why?
Yet, it works fine in gcj:
$ gcj --main=A -o a *.java && ./a
A static{}
A main
B.x: 0
C.x: 0
Why?
Also, if I get rid of the threads,
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);
}
}
It works fine in both java and 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
And all the variables are set to 0. Why? Shouldn't this fail to compile since the variables are static final
and are never assigned anywhere?