Java 为什么A.class.getClassLoader()不返回loader.loadClass(“A”)使用的加载程序
在这个测试用例中,我们通过一个特定的类加载器实例加载一个类Java 为什么A.class.getClassLoader()不返回loader.loadClass(“A”)使用的加载程序,java,reflection,classloader,Java,Reflection,Classloader,在这个测试用例中,我们通过一个特定的类加载器实例加载一个类a,即GwClassLoader。但是,A.class.getClassLoader()没有检索到该类加载器?这是测试用例: class A{ static { ClassLoader loader = A.class.getClassLoader(); System.out.println("A.<cinit>: " + loader); } } class ClassLoaderGw extend
a
,即GwClassLoader
。但是,A.class.getClassLoader()
没有检索到该类加载器?这是测试用例:
class A{
static {
ClassLoader loader = A.class.getClassLoader();
System.out.println("A.<cinit>: " + loader);
}
}
class ClassLoaderGw extends ClassLoader { }
public class App {
public static void main(String [] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoaderGw loader = new ClassLoaderGw();
System.out.println("Main: " + loader);
Class<?> klass = loader.loadClass("A");
Object obj = klass.newInstance();
}
}
如何在类A
的静态构造函数中获取GwClassLoader
的实例?中描述了这一点:
加载具有指定二进制名称的类。此方法的默认实现按以下顺序搜索类:
- 调用findLoadedClass(字符串)检查该类是否已加载
- 调用父类加载器上的loadClass方法。如果父级为null,则使用虚拟机内置的类加载器
- 调用findClass(String)方法来查找该类
ClassLoader
将sun.misc.Launcher$AppClassLoader1
作为父级,因为如的Javadoc中所述(在ClassLoaderGw
类中隐式调用,因为没有显式构造函数):
使用getSystemClassLoader()方法返回的类加载器作为父类加载器,创建一个新的类加载器
ClassLoaderGw
只是扩展ClassLoader
,而不重写任何方法。因此,它将遵循标准loadClass
方法()的策略。。。首先委托给父类加载器
在本例中,您的类位于父类加载器的类路径上,因此将加载它
最后一个难题是getClassLoader()
返回实际加载类的类加载器,而不是您要求加载的类加载器
如何在类A的静态构造函数中获取GwClassLoader的实例
基本上,你不能。。。除非GwClassloader
负责加载类A
你能让它工作吗?好。。。如果您使用不同的类加载策略,您可以。大概如果GwClassloader
能够找到A
的字节码并调用defineClass
本身,那么它将是A
的类加载器
但是,您需要担心父类加载器也可能加载类A
。如果发生这种情况,您可能同时存在两种不同的A
类型。这可能会在意外的地方导致类强制转换异常。已解决。通过调用defineClass
,它将成为预期类的classloader
。这里是针对的新实现
Main: ClassLoaderGw@6d06d69c
A.<cinit>: sun.misc.Launcher$AppClassLoader@73d16e93