Order of Initialization in Java

Ashutosh Mohanty
3 min readJul 3, 2022

The order of Initialization is the sequence in which components are loaded in a Java class. Components that play a key role are:

  1. Static Blocks
static Map<String,String> timezones = new HashMap<>();
static {
timezones.put("MDT","US/Mountain Daylight");
timezones.put("IST","Indian Standard Time");
timezones.put("MST","US/Mountain Standard");
}

2. Instance Blocks

private LocalDate todayDate ;
{
todayDate = LocalDate.now();
}

3. Constructor

class Foo {
public Foo() {
System.out.println("Default constructor");
}
}

Now, we have to understand how inheritance affects the loading of these components. Let's say that Foo is the super-class of Bar. Both of these classes have static blocks, instance blocks, and constructors (default and argument).

We will go through an example and then understand what is happening behind the scenes

class Foo looks like this:

class Foo {
static { System.out.print("Static 1, "); }

{ System.out.print("Instance 1, "); }

public Foo() {
System.out.print("Foo Constructor, ");
}

public Foo(int a, String b) {
System.out.print("Foo args-constructor, ");
}
}

class Bar :

class Bar extends Foo {
static { System.out.print("Static 2, "); }

{ System.out.print("Instance 2, "); }

public Bar() {
System.out.print("Bar Constructor, ");
}

public Bar(int a,String b) {
System.out.println("Bar args-constructor");
}
}

Now let's invoke the Bar constructor from the main method: (Fig: 1)

public class Test {
public static void main(String[] args) {
Bar b1 = new Bar();
}
}
Output:
Static 1, Static 2, Instance 1, Foo Constructor, Instance 2, Bar Constructor,

Now let’s invoke the Bar parameterized constructor from the main method: (Fig: 2)

public class Test {
public static void main(String[] args) {
Bar b2 = new Bar(10,"Ashutosh");
}
}
Output:
Static 1, Static 2, Instance 1, Foo Constructor, Instance 2, Bar args-constructor

So when there is a child class and we call the constructor of the child class following order will be followed:

  1. Static Blocks of Super class and Child class will be loaded
  2. Instance block of the Super class loads
  3. Constructor of theSuper class loads
  4. Instance block of the Child class loads
  5. Constructor of the Child class loads

( Catch: Constructor will load only if all instance blocks are loaded )

Now, if we analyze the output in Fig: 1 we saw that the static block of Foo is loaded followed by the static block of Bar, then the instance block and constructor of Foo load followed by the instance block and constructor of Bar. The point to note here is that if we had multiple static and instance blocks then those would have been executed in the same sequence they were written in the class. The constructor of any class will load after all the instance blocks in that class have been executed.

Now, let’s analyze the output in Fig: 2. The output is pretty similar to the previous one, but with a small deviation. When we have both default and parameterized Constructor in Super and Child classes, then the parameterized Constructor in the child class calls the Default Constructor implicitly.

class Bar extends Foo {
public Bar(int a,String b) {
super(); //super() is invoked implicity at run-time
System.out.println("Bar args-constructor");
}

So for this reason in Fig:2 we find the Foo constructor in the output instead of the Foo args-constructor.

If we had explicitly called the parameterized super constructor then we would find Foo args-constructor in the output, as shown in the below snippets.

class Bar extends Foo {
public Bar(int a,String b) {
super(a,b);
System.out.println("Bar args-constructor");
}
//existing codes
}

Output from the main method:

public class Test {
public static void main(String[] args) {
Bar b2 = new Bar(10,"Ashutosh");
}
}
Output:
Static 1, Static 2, Instance 1, Foo args-constructor, Instance 2, Bar args-constructor

Hope this article was able to deliver you this concept of initialization. Let me know in the comments how to improve this article.

--

--