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
.
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.