I have the following code:
class Foo {
static { //static initializer block
System.out.print("Foo");
}
class Bar {
static { //static initializer block
System.out.print("Bar");
}
}
public static void main(String[] args) { // => This will print "FooBar" to the console
new Foo().new Bar();
}
}
public class Main {
public static void main(String[] args) { // This will print "BarFoo" to the console
new Foo().new Bar();
}
}
As the comments say, they will print different result on independent invocation of main methods. Why the placement of main method in this case affect the result printed to the screen?
new Foo().new Bar()is compiled to the following bytecode:Note that it is
Barthat is first created (thoughFoo's constructor is called first). Thenewinstruction is what causes a class to be initialised (see spec), not the constructor call. The When a class is initialised, its static initialisers run (see spec).Just in case you are not aware, non-static inner classes are implemented by having the constructors take an extra parameter, which serves as the enclosing instance.
new Foo().new Bar()is basically sayingnew Foo.Bar(new Foo()), but only the former syntax is valid.I'm not sure if such an output is behaviour guaranteed by the spec. It could technically have been compiled in a way such that
NEW Foooccurs first, but that would require an additional variable, as if you wrote:So when you put
new Foo().new Bar()in an unrelated class,Bargets initialised first, and soBaris printed first.When you put
new Foo().new Bar()in a static method declared inFoo, however,Foowill be initialised before any of thenewinstructions, henceFoois printed first. This is because calling a static method inFoocausesFooto be initialised.See all the conditions for a class or interface
Tto be initialised in the spec:Note that the first one refers to the execution of the
newinstruction, not the constructor call.