我的自定义 java ClassLoader 加载了一个类,但 clazz.getClassLoader() 是 myC



我有一个类加载器,看起来像这样:

@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());

一个被类加载器加载的类不应该是那个类加载器吗?我想要这样做的原因是,我正在加载的这个类引用的任何类(className(,我也希望它被MyClassLoader加载。如果这不是任何工作方式,它是如何工作的?我该如何做我想做的事情?

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

defineClass()是关键方法;它在 JVM 中调用一些本机代码,这些代码创建类并将其关联到其类加载器。

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

我希望这些链接可以帮助您: baeldung 爪哇世界

最新更新