Wednesday, 20 July 2022

When is a class or interface is initialized or loaded in Java?

As per Java language specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1),

 

1. A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

 

a.   T is a class and an instance of T is created.

b.   T is a class and a static method declared by T is invoked.

c.    A static field declared by T is assigned.

d.   A static field declared by T is used and the field is not a constant variable

e.   T is a top level class and an assert statement lexically nested within T is executed.

 

2. A reference to a static field causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

 

3. Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.

 

Let’s experiment the same with below example.

 


A.java

package com.sample.app.dto;

public class A {

	static {
		System.out.println(A.class + " is loaded");
	}
	
	public A() {
		System.out.println(A.class + " constructor is loaded");
	}

}

B.java

package com.sample.app.dto;

public class B{
	
	static {
		System.out.println(B.class + " is loaded");
	}
	
	public static void sayHi() {
		System.out.println("Executing B's sayHi method");
	}
	
	public B() {
		System.out.println(B.class + " constructor is loaded");
	}
	
}

C.java

package com.sample.app.dto;

public class C {

	public static double PI;

	static {
		System.out.println(C.class + " is loaded");
	}

	public C() {
		System.out.println(C.class + " constructor is loaded");
	}
}

D.java

package com.sample.app.dto;

public class D {

	public static double PI = 3.14;

	static {
		System.out.println(D.class + " is loaded");
	}

	public D() {
		System.out.println(D.class + " constructor is loaded");
	}
}

E.java

package com.sample.app.dto;

public class E {
	public static final double PI = 3.14;

	static {
		System.out.println(E.class + " is loaded");
	}

	public E() {
		System.out.println(E.class + " constructor is loaded");
	}
}

F.java

package com.sample.app.dto;

public class F {

	static {
		System.out.println(F.class + " is loaded");
	}

	public F() {
		System.out.println(F.class + " constructor is loaded");
	}
}

App.java

package com.sample.app;

import com.sample.app.dto.A;
import com.sample.app.dto.B;
import com.sample.app.dto.C;
import com.sample.app.dto.D;
import com.sample.app.dto.E;

public class App {
	public static void main(String[] args) throws ClassNotFoundException {

		System.out.println("Getting an instance of the class A");
		A a = new A();
		
		System.out.println("\nCalling B's static method");
		B.sayHi();
		
		System.out.println("\nSetting some value to C's static field");
		C.PI = 3.14;
		
		System.out.println("\nUsing D's static filed");
		System.out.println("D.PI = " + D.PI);
		
		System.out.println("\nUsing E's static filed");
		System.out.println("E.PI = " + E.PI);
		
		System.out.println("\nGet the class object of F");
		Class.forName("com.sample.app.dto.F");
		
	}
}

Output

Getting an instance of the class A
class com.sample.app.dto.A is loaded
class com.sample.app.dto.A constructor is loaded

Calling B's static method
class com.sample.app.dto.B is loaded
Executing B's sayHi method

Setting some value to C's static field
class com.sample.app.dto.C is loaded

Using D's static filed
class com.sample.app.dto.D is loaded
D.PI = 3.14

Using E's static filed
E.PI = 3.14

Get the class object of F
class com.sample.app.dto.F is loaded

In all the dto classes (A.java, B.java etc.,), I used static blocks to demonstrate this application. Static blocks are executed when the class gets loaded by a class loader.

 

Scenario 1: A’s static block is called when I am requesting for an instance of class A.

 

Scenario 2: B’s static block is called, when I am calling B’s static sayHi method.

 

Scenario 3: C’s static block is called when I assign some value if the static variable PI.

 

Scenario 4: D’s static block is called, when I used the D’s static field PI.

 

Scenario 5: Since I am using a constant of the class E, static block is not called here, same is documented in Java specification 1.d.

 

Scenario 6: F’s static block is called, when I am getting Class instance of the class F.

 

References

https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

https://self-learning-java-tutorial.blogspot.com/2014/02/static-blocks.html



You may like

Interview Questions

Why System.out.println() is not throwing NullPointerException on null references?

Why should we restrict direct access to instance properties?

Closeable vs AutoCloseable in Java

What is the behaviour of static final method in Java?

How to check two double values for equality?

Why to do explicit type casting from double to float conversion?

No comments:

Post a Comment