Can anyone explain the output of following program? I thought constructors are initialized before instance variables. So I was expecting the output to be \"XZYY\".
To clarify the misconceptions with static - I will simply refer to this small piece of code:
public class Foo {
{ System.out.println("Instance Block 1"); }
static { System.out.println("Static Block 1"); }
public static final Foo FOO = new Foo();
{ System.out.println("Instance Block 2"); }
static { System.out.println("Static Block 2 (Weird!!)"); }
public Foo() { System.out.println("Constructor"); }
static public void main(String p[]) {
System.out.println("In Main");
new Foo();
}
}
Surprise is that the output is as follows:
Static Block 1
Instance Block 1
Instance Block 2
Constructor
Static Block 2 (Weird!!)
In Main
Instance Block 1
Instance Block 2
Constructor
Note that we have a static {}
that is called after two instance {}
. this happens because we throw in the constructor in the middle, interjecting execution order the first time the constructor is called.
Discovered this when I was working on this answer - https://stackoverflow.com/a/30837385/744133.
Basically we observe this to happen:
During the first time an object is initialized, Initialize current object for both static and instance initialization intermixed based on order of occurrence
For all next initializations, only do the instance initialization in the order of occurrence, as static initialization already happened.
I need to research how the mix of inheritance, and both explicit and implicit calls to super and this will affect this, and will update with findings. It would be likely similar to the other supplied answers, except that they got it wrong with the static initialization.
If you look at the decompiled version of the class file
class X {
Y b;
X() {
b = new Y();
System.out.print("X");
}
}
class Y {
Y() {
System.out.print("Y");
}
}
public class Z extends X {
Y y;
Z() {
y = new Y();
System.out.print("Z");
}
public static void main(String args[]) {
new Z();
}
}
You can find that the instance variable y
is moved inside the constructor, so the execution sequence is as follows
Z
X
X
constructor new Y()
is called.new Y()
Y
All the instance variables are initialized by using constructor statements.
When you invoke a constructor, the instance variable initializers run before the body of the constructor. What do you think the output of the below program ?
public class Tester {
private Tester internalInstance = new Tester();
public Tester() throws Exception {
throw new Exception("Boom");
}
public static void main(String[] args) {
try {
Tester b = new Tester();
System.out.println("Eye-Opener!");
} catch (Exception ex) {
System.out.println("Exception catched");
}
}
}
The main method invokes the Tester constructor, which throws an exception. You might expect the catch clause to catch this exception and print Exception catched.
But if you tried running it, you
found that it does nothing of that sort and It throws a StackOverflowError
.
The correct order of initialisation is:
See sections §2.17.5-6 of the Java Virtual Machine Specification.
The initialization sequence is specified in JLS 12.5:
1.First, memory is allocated for the new object
2.Then all instance variables in the object (including the ones defined in this class and all of its superclasses) are initialized to their default values
3.Finally, the constructor is called.
https://stackoverflow.com/questions/26552799/which-run-first-default-values-for-instance-variables-or-super-constructors