When doees the instance variable get initialized? Is it after the constructor block is done or before it?
Consider this example:
public abstract class Parent {
public Parent(){
System.out.println("Parent Constructor");
init();
}
public void init(){
System.out.println("parent Init()");
}
}
public class Child extends Parent {
private Integer attribute1;
private Integer attribute2 = null;
public Child(){
super();
System.out.println("Child Constructor");
}
public void init(){
System.out.println("Child init()");
super.init();
attribute1 = new Integer(100);
attribute2 = new Integer(200);
}
public void print(){
System.out.println("attribute 1 : " +attribute1);
System.out.println("attribute 2 : " +attribute2);
}
}
public class Tester {
public static void main(String[] args) {
Parent c = new Child();
((Child)c).print();
}
}
OUTPUT:
Parent Constructor
Child init()
parent Init()
Child Constructor
attribute 1 : 100
attribute 2 : null
When the memory for the atribute 1 & 2 are allocated in the heap ?
Curious to know why is attribute 2 is NULL ?
Are there any design flaws?
After consuming the answers and link provided here is my digest observation :
Here is the flow:
Enter Child class constructor. Child(){ ... }
Invoke explicit super() [invoking Parent class constructor].
Enter Parent() { ... } class constructor
Invoke implicit super() [invoking Object class constructor]
Enter Object(){ } (No super constructor calls)
Recursive call for super class constructor end here.
Returns for Object class constructor
Now in Parent class constructor...Instance initializers and Instance variable initializers of Parent class gets executed.
Rest of the Parent class constructor is executed and returns
Now in Child class constructor. Instance initializers and Instance variable initializers of Child class gets executed.
Then rest of the Child class constructor is executed and finishes the object initialization process.
The reason attribute2 was NULL because
Are there any design flaws?
As Fabian Barney mention ::::: It's generally bad practise to call methods inside constructor that can be overridden by subclasses.
When the memory for the atribute 1 & 2 are allocated in the heap ? Still figuring out. Appreciate any pointers.
Thanks for Mike and Fabian
The memory for the object as a whole is allocated when the
new
operator is invoked, before thejava.lang.Object
constructor is entered. Memory is allocated for individualInteger
instances ininit
, but there is no point when memory is allocated for individual properties -- only whole objects.The
init
method is called in the super constructor, soattribute2
is assignednew Integer(200)
, and then the subclass constructor is invoked which applies property initializers in the order they appear in the source code. This lineoverwrites the value assigned by
init()
tonull
.If you add a call to
right after your call to
super();
then this will become apparent.Calling sub-class methods before the base class has finished initializing is dangerous. The sub-class might rely on its base-class's invariants to protect its own invariants, and if the base-class constructor has not completed, then its invariants may not hold.
This is also likely to confuse C++ programmers and the like who would expect a call to
init
from the base class to invoke the base class's version since C++ rewrites the vtable pointer as constructors are entered.See The Java Language Specification for all the gory details.