Often when there are static initializer,constructor initializers and constructor blocks are there , programmer finds it hard to find the flow as which block will execute first when the program is run.
I will try to look into the details of this and try to look into the reason for the same.
Here is the sample code :-
class Parent
{
static
{
System.out.println("Parent Static Initializer Block");
}
{
System.out.println("Parent Constructor Initialization Block");
}
Parent()
{
System.out.println("Parent Constructor");
}
}
class Child extends Parent
{
static
{
System.out.println("Child Static Initializer Block");
}
{
System.out.println("Child Constructor Initialization Block");
}
Child()
{
System.out.println("Child Constructor");
}
}
class Temp
{
static
{
System.out.println("Temp Static Initializer Block");
}
{
System.out.println("Temp Constructor Initialization Block");
}
Temp()
{
System.out.println("Temp Constructor");
}
}
class TestJava
{
static
{
System.out.println("TestJava Static Initializer Block");
}
{
System.out.println("TestJava Constructor Initialization Block");
}
public static void main(String[] args)
{
System.out.println("Inside Main");
Child c = new Child();
}
}
Output of above program is :-
TestJava Static Initializer Block
Inside Main
Parent Static Initializer Block
Child Static Initializer Block
Parent Constructor Initialization Block
Parent Constructor
Child Constructor Initialization Block
Child Constructor
Ohh..I was expecting main will execute first then static initializer of TestJava , then Parent class constructor and then child class constructor but its not like that.
{
static
{
System.out.println("Parent Static Initializer Block");
}
{
System.out.println("Parent Constructor Initialization Block");
}
Parent()
{
System.out.println("Parent Constructor");
}
}
class Child extends Parent
{
static
{
System.out.println("Child Static Initializer Block");
}
{
System.out.println("Child Constructor Initialization Block");
}
Child()
{
System.out.println("Child Constructor");
}
}
class Temp
{
static
{
System.out.println("Temp Static Initializer Block");
}
{
System.out.println("Temp Constructor Initialization Block");
}
Temp()
{
System.out.println("Temp Constructor");
}
}
class TestJava
{
static
{
System.out.println("TestJava Static Initializer Block");
}
{
System.out.println("TestJava Constructor Initialization Block");
}
public static void main(String[] args)
{
System.out.println("Inside Main");
Child c = new Child();
}
}
Output of above program is :-
TestJava Static Initializer Block
Inside Main
Parent Static Initializer Block
Child Static Initializer Block
Parent Constructor Initialization Block
Parent Constructor
Child Constructor Initialization Block
Child Constructor
Ohh..I was expecting main will execute first then static initializer of TestJava , then Parent class constructor and then child class constructor but its not like that.
Lets look into class loading,linking and initalization part -
"The Java virtual machine starts execution by invoking the main method of specified class and passing it a single argument, which is an array of strings.
This causes the specified class to be loaded , linked to other types that it uses, and initialized .
The method main must be declared public, static, and void. "
Ref (http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19075)
Loading :- Loading involves the process of finding the binary form of a class , constructing object to represent this class from this binary form.ClassLoader and its subclasses performs loading operations.
Linking :- A class is loaded before it is linked. Linking is the process of combining binary form of a class to runtime environment of virtual machine.
Initialization :- Initialization involves executing static initializers and field initializers.
Static initializers are executed only once when class is initialized and field initializers executed
everytime new instance of class is created.
If we go back to our example, class TestJava is loaded first as it has main methods which makes entry point for JVM.Once it is loaded it will get linked and then initialized.
Upon initialization of class TestJava , static intializers will be executed so "TestJava Static Initializer Block" is printed.
Loading :- Loading involves the process of finding the binary form of a class , constructing object to represent this class from this binary form.ClassLoader and its subclasses performs loading operations.
Linking :- A class is loaded before it is linked. Linking is the process of combining binary form of a class to runtime environment of virtual machine.
Initialization :- Initialization involves executing static initializers and field initializers.
Static initializers are executed only once when class is initialized and field initializers executed
everytime new instance of class is created.
If we go back to our example, class TestJava is loaded first as it has main methods which makes entry point for JVM.Once it is loaded it will get linked and then initialized.
Upon initialization of class TestJava , static intializers will be executed so "TestJava Static Initializer Block" is printed.
No other static initializer blocks , so main method will print "Inside Main" .
Line Child c = new Child(); makes class loader to load Child class but since ClassLoader uses delegation model , Parent class will get loaded before Child class.
Once Parent class is laoded it's static initializer block will execute first so "Parent Static Initializer Block" gets printed.
In the same fashion Child class gets loaded and its static initializer block will execute which makes "Child Static Initializer Block" printed.
Constructor of Child class is invoked which in turn invokes parent class constructor.
But since constructor initialization blocks included in constructor at runtime it will execute first , so"Parent Constructor Initialization Block" will get printed followed by "Parent Constructor".
Once constructor of parent class is invoked, child class constructor will be invoked.So the order will be same as for Parent class "Child Constructor Initialization Block" followed by "Child Constructor".
Constructor of Child class is invoked which in turn invokes parent class constructor.
But since constructor initialization blocks included in constructor at runtime it will execute first , so"Parent Constructor Initialization Block" will get printed followed by "Parent Constructor".
Once constructor of parent class is invoked, child class constructor will be invoked.So the order will be same as for Parent class "Child Constructor Initialization Block" followed by "Child Constructor".