Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about class loading

Tags:

java

I am a little bit confused about when the class actually is loaded by the JVM. I noticed that the class loader will load the class when the class is referenced.

I am using java6 environment and run with -verbose:class for tracking class loading. For example:

MyObject obj = new MyObject(); //MyObject.class will be loaded

However, in this case

// ClassC.java
package com.gogog22510.test;
public class ClassC {}

// ClassB.java
package com.gogog22510.test;
public class ClassB extends ClassC {}

// ClassA.java
package com.gogog22510.test;
public class ClassA {
    public ClassC test() {
        return new ClassB();
    }
}

when my test program initialize ClassA, it will load all ClassA, ClassB, and ClassC even though I haven't invoked test()

// TestClassLoad.java
package com.gogog22510.test;
public class TestClassLoad {
    public static void main(String[] args) {
        // initialize ClassA
        System.out.println("start load ClassA");
        new ClassA();
    }
}

console:

[Loaded TestClassLoad from file:/.../bin/]
start load ClassA
[Loaded ClassA from file:/C:/.../bin/]
[Loaded ClassC from file:/C:/.../bin/]
[Loaded ClassB from file:/C:/.../bin/]

But if I change the test() method's return type like this:

// ClassA.java
package com.gogog22510.test;
public class ClassA {
    public ClassB test() {
        return new ClassB();
    }
}

ClassLoader will only load ClassA into perm space unless I invoke the test() method.

console:

[Loaded TestClassLoad from file:/.../bin/]
start load ClassA
[Loaded ClassA from file:/C:/.../bin/]

Why does the ClassLoader load all three class before I explicitly call the method?

like image 433
gogog22510 Avatar asked Sep 28 '22 08:09

gogog22510


1 Answers

I think it happens during the verification step, to make sure that ClassC is a subclass of ClassB, for purposes of validating the return type.

Here, they say:

If the method returns a reference type, it must do so using an areturn instruction, and the type of the returned value must be assignment compatible (JLS §5.2) with the return descriptor (§4.3.3) of the method.

See also this:

Verification (§4.10) ensures that the binary representation of a class or interface is structurally correct (§4.9). Verification may cause additional classes and interfaces to be loaded (§5.3) but need not cause them to be verified or prepared.

like image 89
Vlad Avatar answered Oct 13 '22 02:10

Vlad