[英]which classloader uses for composition classes
分析以下代碼:
public class A {
public void foo() {
B b = new B(); // row#1
b.toString();
}
據我了解,在row#1
,類是由A
類的類加載器加載的。
考慮B
類:
class B {
C c = new C();
}
請闡明將使用哪個類加載器來加載類C
在獲得類B
的類加載器並編寫以下代碼之后:
classloaderOfClassB.loadClass("A")
請說明所有涉及的類將使用什么類加載器。
我用以下示例產生以下輸出。
不知道類C
,我假設它位於A
內。 如果不是,此stacktrace應該可以為您提供幫助。
AFAIK, A
加載C
產量
java.lang.Thread.getStackTrace(Thread.java:1568)
A$C.<init>(Main.java:15)
<-在這里
A$B.<init>(Main.java:10)
A.foo(Main.java:5)
A.main(Main.java:23)
例
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();
}
}
如果一個類依賴於其他類,例如在您的示例中,類A依賴於類B,而類B本身依賴於類C,另外這些類尚未加載,則當前類的類加載器將用於嘗試加載從屬類。類。
實際上,以您的示例為例,類A的類加載器也將用於加載類B和C。
該聲明
classloaderOfClassB.loadClass("A")
現在將加載類A並將類加載器設置為classloaderOfClassB
引用的實例。 然后,將使用相同的類加載器加載類A中所有其他尚未加載的依賴項。並且由於類B已由相同的加載器加載,因此一切都很好。
此機制確保在以下情況下類加載正常進行:
考慮有一個可插入的應用程序,其中插入意味着將JAR文件(不是類路徑的一部分)放入指定的目錄中。 然后,您可以使用由JAR文件構造的URLClassLoader
(當然是URL形式)來加載此新JAR的類和資源。 由於所有類現在都具有此URLClassLoader
作為其類加載器,因此所有進一步的依賴項將由相同的URLClassLoader
加載,這是正確的,因為只有此URLClassLoader
此JAR文件。
OSGi將使用類B的類加載器加載類C。因此,例如,如果B和C駐留在同一個包中,但是C在內部包中,則它仍然可以工作。 原因是,當類A的類加載器加載類B時,它將委托給B所在的捆綁軟件的類加載器。 因此,B將使用其所在的捆綁包的類加載器加載。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.