哪个类加载器用于组合类

时间:2014-04-30 10:16:10

标签: java osgi classloader

分析以下代码:

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")

请说明哪个类加载器将用于所有涉及的类。

3 个答案:

答案 0 :(得分:1)

我使用下面的示例生成以下输出。

如果不知道班级C所在的位置,我假设它位于A内。如果没有,这个堆栈跟踪应该可以帮到你。

AFAIK,A加载C

<强>输出

  

java.lang.Thread.getStackTrace(Thread.java:1568)
  A$C.<init>(Main.java:15) &lt; - HERE
  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();
    }
}

答案 1 :(得分:0)

如果一个类依赖于其他类,比如在你的示例中,类A依赖于本身依赖于类C的类B,而且这些类还没有加载,那么当前类的类加载器将用于尝试加载依赖类。

事实上,对于您的示例,类A的类加载器也将用于加载类B和C.

声明

classloaderOfClassB.loadClass("A")

现在将加载A类并将类加载器设置为classloaderOfClassB引用的实例。然后将使用相同的类加载器来加载A类中所有其他尚未加载的依赖项。并且由于类B已经由同一个加载器加载,所以一切都很好。

此机制可确保以下方案中的类加载效果良好:

考虑使用可插拔应用程序,其中插件意味着将JAR文件(不属于类路径的一部分)放入指定的目录中。然后,使用由JAR文件构造的URLClassLoader加载此新JAR的类和资源(当然,以URL形式)。由于所有类现在都将此URLClassLoader作为其类加载器,所有其他依赖项将由相同的URLClassLoader加载,这是正确的,因为只有此URLClassLoader查看此JAR文件

答案 2 :(得分:0)

OSGi将使用类B的类加载器来加载类C.例如,如果B和C驻留在同一个包中但C在内部包中,它仍然可以工作。原因是,当类A的类加载器加载类B时,它将委托给B所在的bundle的类加载器。所以B将加载它所在的bundle的类加载器。