我的自定义 java ClassLoader 加载一个 class,但 clazz.getClassLoader() 是 myClassLoader.getParent(),而不是 myClassLoader

My custom java ClassLoader loads a class, but clazz.getClassLoader() is myClassLoader.getParent(), not myClassLoader

我有一个 classloader,它看起来像这样:

@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    if(isExcluded(name)) return super.loadClass(name, resolve);
    //  irrelevant... it always returns above
    InputStream s = getResourceAsStream(name.replace('.', '/') + ".class");
    if(s == null) throw new ClassNotFoundException(name);
    ClassReader reader;
    try {
        reader = new ClassReader(s);
    } catch(IOException e) {
        throw new RuntimeException(e);
    }

    ClassWriter writer = new ClassWriter(Opcodes.ASM4);
    ClassVisitor v = new RemappingClassAdapter(writer, remapper);

    reader.accept(v, 0);

    byte[] bytes = writer.toByteArray();
    Class<?> c = defineClass(name, bytes, 0, bytes.length);
    if(resolve) {
        resolveClass(c);
    }
    return c;
}

那我做

MyClassLoader loader = new MyClassLoader(Main.class.getClassLoader());
Class<?> c = loader.loadClass(className, true); // also tried false, and loader.loadClass(className)
c.getClassLoader(); // AppClassLoader instead of MyClassLoader, why?
Method m = c.getDeclaredMethod(methodName);
return m.invoke(c.newInstance());

不应该由 classloader 加载的 class,它的 classloader 是 classloader 吗?我想要这个的原因是,我正在加载的 class 引用的任何 class (className),我希望它也被 MyClassLoader 加载。如果那不是任何事情的运作方式,那么它是如何运作的?我该如何做我想做的事?

事实上,我没有使用过自定义 ClassLoader,但据我了解,在这些 ClassLoader 对象的级别上,它们通过父/子关系相互关联。 这意味着当一个 ClassLoader 要加载一个 class 时,它首先询问它的父 ClassLoader 它是否可用,在这种情况下它加载它。如果父 ClassLoader 无法加载它,则将请求委托给下一个父类,直到到达 BootStrapClassLoader。如果父类加载器的 none 可以加载 class,当前的 class 加载器将尝试从其可用路径加载它。找不到它会导致 ClassNotFoundException。

希望这些链接对您有所帮助:baeldung javaworld

当 class 加载器委托给其父加载器时,与加载的 class(由 Class.getClassLoader() 返回)关联的 class 加载器是父加载器。那是因为父加载器是调用 defineClass().

的加载器

defineClass()是关键方法;它调用 JVM 中的一些本机代码来创建 class 并将其关联到其 class 加载程序。