When and how a Java class is loaded and initialized?

In Java, you first write a .java file which is then compiled to .class file during compile time. Java is capable of loading classes at run time. The confusion is what is the difference between "load" and "initialize". When and how is a Java class loaded and initialized? It can be clearly illustrated by using a simple example below.

What does it mean by saying "load a class"?

C/C++ is compiled to native machine code first and then it requires a linking step after compilation. What the linking does is combining source files from different places and form an executable program. Java does not do that. The linking-like step for Java is done when they are loaded into JVM.

Different JVMs load classes in different ways, but the basic rule is only loading classes when they are needed. If there are some other classes that are required by the loaded class, they will also be loaded. The loading process is recursive.

When and how is a Java class loaded?

In Java, loading policies is handled by a ClassLoader. The following example shows how and when a class is loaded for a simple program.

TestLoader.java

package compiler;
public class TestLoader {
	public static void main(String[] args) {
		System.out.println("test");
	}
}

A.java

package compiler;
public class A {
	public void method(){
		System.out.println("inside of A");
	}
}

Here is the directory hierarchy in eclipse:

dir-hierarchy

By running the following command, we can get information about each class loaded. The "-verbose:class" option displays information about each class loaded.

java -verbose:class -classpath /home/ron/workspace/UltimateTest/bin/ compiler.TestLoader

Part of output:

 
[Loaded sun.misc.JavaSecurityProtectionDomainAccess from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.ProtectionDomain$2 from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.ProtectionDomain$Key from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.Principal from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded compiler.TestLoader from file:/home/xiwang/workspace/UltimateTest/bin/]
test
[Loaded java.lang.Shutdown from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]

Now If we change TestLoader.java to:

package compiler;
public class TestLoader {
	public static void main(String[] args) {
		System.out.println("test");
		A a = new A();
		a.method();
	}
}

And run the same command again, the output would be:

[Loaded sun.misc.JavaSecurityProtectionDomainAccess from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.ProtectionDomain$2 from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.ProtectionDomain$Key from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.security.Principal from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded compiler.TestLoader from file:/home/xiwang/workspace/UltimateTest/bin/]
test
[Loaded compiler.A from file:/home/xiwang/workspace/UltimateTest/bin/]
inside of A
[Loaded java.lang.Shutdown from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /usr/local/java/jdk1.6.0_34/jre/lib/rt.jar]

We can see the difference highlighted in red. A.class is loaded only when it is used. In summary, a class is loaded:

  • when the new bytecode is executed. For example, SomeClass f = new SomeClass();
  • when the bytecodes make a static reference to a class. For example, System.out.

When and how is a Java class initialized?

A class is initialized when a symbol in the class is first used. When a class is loaded it is not initialized.

JVM will initialize superclass and fields in textual order, initialize static, final fields first, and give every field a default value before initialization.

Java Class Instance Initialization is an example that shows the order of execution for field, static field and constructor.

References:
1. Java class loader
2. Java class loading
3. Class and object initialization

Category >> JVM/Compiler  
  • MengWoo

    There is a typo in the ‘simple java’ that links to this page whan…