简体   繁体   中英

which classloader uses for composition classes

Analyze the following code:

public class A {
    public void foo() {
        B b = new B();  // row#1
        b.toString();  
}

As I understand, in row#1 class loads by classloader of class A .

Consider class B :

class B {
   C c = new C();
}

Please clarify which classloader will use for loading class C .

UPDATE

after I get classloader of class B and write following code:

classloaderOfClassB.loadClass("A")

please clarify what classloader will use for all involve classes.

I produce the following output with the example below.

Without knowledge where the class C resides, I am assuming that it resides within A . If it does not, this stacktrace should assist you.

AFAIK, A loads C .

Output

java.lang.Thread.getStackTrace(Thread.java:1568)
A$C.<init>(Main.java:15) <-- HERE
A$B.<init>(Main.java:10)
A.foo(Main.java:5)
A.main(Main.java:23)

Example

import java.lang.StackTraceElement;

class A {
    public void foo() {
        B b = new B();  // row#1
        b.toString();  
    }

    class B {
        C c = new C();
    }

    class C {
        public C() {
            for (StackTraceElement ele : Thread.currentThread().getStackTrace()) {
                System.out.println(ele);
            }
        }
    }

    public static void main (String[] args) {
        A a = new A();
        a.foo();
    }
}

If a class depends on other classes, like in your example class A depends on class B that itself depends on class C, and additionally these classes are not yet loaded, the class loader of the current class will be used for trying to load the dependent classes.

In fact, for your example, the class loader of class A will also be used for loading the classes B and C.

The statement

classloaderOfClassB.loadClass("A")

will now load class A and set the class loader to the instance that classloaderOfClassB refers to. This same class loader will be then be used to load all other not yet loaded dependencies in class A. And as class B already was loaded by the same loader, everything is fine.

This mechanism assures that class loading in the following scenario works well:

Consider having a pluggable application, in which plugging-in means to put JAR files (which are not part of the class path) into a specified directory. You then load classes and resources of this new JAR with a URLClassLoader that was constructed with the JAR file (in URL form, of course). As all classes now have this URLClassLoader as their class loader, all further dependencies will be loaded by the same URLClassLoader , which is the right thing, as only this URLClassLoader looks into this JAR file.

OSGi will use the class loader of class B to load class C. So for example if B and C reside in the same bundle but C is in an internal package it will still work. The reason is that when class B is loaded by the class loader of class A it will delegate to the classloader of the bundle where B resides. So B will be loaded with the class loader of the bundle it resides in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM