简体   繁体   English

哪个classloader用于组合类

[英]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 . 据我了解,在row#1 ,类是由A类的类加载器加载的。

Consider class B : 考虑B类:

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

Please clarify which classloader will use for loading class C . 请阐明将使用哪个类加载器来加载类C

UPDATE UPDATE

after I get classloader of class B and write following code: 在获得类B的类加载器并编写以下代码之后:

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 . 不知道类C ,我假设它位于A内。 If it does not, this stacktrace should assist you. 如果不是,此stacktrace应该可以为您提供帮助。

AFAIK, A loads C . AFAIK, A加载C

Output 产量

java.lang.Thread.getStackTrace(Thread.java:1568)
A$C.<init>(Main.java:15) <-- HERE A$C.<init>(Main.java:15) <-在这里
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. 如果一个类依赖于其他类,例如在您的示例中,类A依赖于类B,而类B本身依赖于类C,另外这些类尚未加载,则当前类的类加载器将用于尝试加载从属类。类。

In fact, for your example, the class loader of class A will also be used for loading the classes B and C. 实际上,以您的示例为例,类A的类加载器也将用于加载类B和C。

The statement 该声明

classloaderOfClassB.loadClass("A")

will now load class A and set the class loader to the instance that classloaderOfClassB refers to. 现在将加载类A并将类加载器设置为classloaderOfClassB引用的实例。 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. 然后,将使用相同的类加载器加载类A中所有其他尚未加载的依赖项。并且由于类B已由相同的加载器加载,因此一切都很好。

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. 考虑有一个可插入的应用程序,其中插入意味着将JAR文件(不是类路径的一部分)放入指定的目录中。 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). 然后,您可以使用由JAR文件构造的URLClassLoader (当然是URL形式)来加载此新JAR的类和资源。 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. 由于所有类现在都具有此URLClassLoader作为其类加载器,因此所有进一步的依赖项将由相同的URLClassLoader加载,这是正确的,因为只有此URLClassLoader此JAR文件。

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. OSGi将使用类B的类加载器加载类C。因此,例如,如果B和C驻留在同一个包中,但是C在内部包中,则它仍然可以工作。 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. 原因是,当类A的类加载器加载类B时,它将委托给B所在的捆绑软件的类加载器。 So B will be loaded with the class loader of the bundle it resides in. 因此,B将使用其所在的捆绑包的类加载器加载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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