Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How JVM loads parent classes in Java

Code:

class A {
    static {
        System.out.println("loading A static 1");
    }
    static {
        System.out.println("loading A static 2 B.c= "+B.c);        
    }
    static {
        System.out.println("loading static 3");
    }
    static int a=10; 
    A(){        
    }
}

class B extends A{
    static {
       System.out.println("loading B A.a= "+A.a);
    }
    static int c = 50;
}
public class Test {
    public static void main(String[] args) {
        new B();
    }
}

Output:

loading A static 1
loading A static 2 B.c= 0
loading static 3
loading B A.a= 10

From this out put can we say that the parent class loads after the child class but child class initialize after the parent class? If so how JVM loads class hierarchies?

like image 984
Kalhan.Toress Avatar asked Apr 01 '14 04:04

Kalhan.Toress


People also ask

How are classes loaded by JVM?

In order to actually load a class, the JVM uses Classloader objects. Every already loaded class contains a reference to its class loader, and that class loader is used to load all the classes referenced from that class.

How does JVM load jars?

JVM loads only the required classes from the Jar when invoked. If application needs a class then the class and all other dependent classes will be loaded.

Which classes are loaded when JVM starts?

Initially when a JVM starts up, nothing is loaded into it. The class file of the program being executed is loaded first and then other classes and interfaces are loaded as they get referenced in the bytecode being executed.

What is parent class loader in Java?

This class loader is responsible for loading only the classes that are from the core Java™ API. These classes are the most trusted and are used to bootstrap the JVM. The extensions class loader can load classes that are standard extensions packages in the extensions directory.


2 Answers

The Java Language Specification explains the process of initializing a class.

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

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

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

  • A static field declared by T is assigned.

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

and with more details

[...]

Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

[...]

If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

[...]

Next, if C is a class rather than an interface, and its superclass SC has not yet been initialized, then recursively perform this entire procedure for SC. If necessary, verify and prepare SC first. If the initialization of SC completes abruptly because of a thrown exception, then acquire LC, label the Class object for C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing SC.

So

new B();

requires that class B be initialized. Because B is a sub class of A, A needs to be initialized. While initializing A, this

static {
    System.out.println("loading A static 2 B.c= "+B.c);        
}

indicates that B needs to be initialized, but B is already in the process of being initialized, so it is ignored for now and A initialization continues. Because B's initialization is not complete, the field c has not yet been initialized to 50, so it prints 0.

A initializing completes. B initializing continues. B initializing completes and Boom! you're done.

like image 127
Sotirios Delimanolis Avatar answered Sep 24 '22 19:09

Sotirios Delimanolis


You can check this by executing it with java -verbose Test:

...
[Loaded A from file:/.../src/main/java/]
[Loaded B from file:/.../src/main/java/]
loading A static 1
loading A static 2 B.c= 0
loading static 3
loading B A.a= 10
...

So no, the parent class is loaded first too.

like image 29
Keppil Avatar answered Sep 24 '22 19:09

Keppil