为什么 A.class.getClassLoader() 没有 return loader.loadClass("A") 使用的加载程序
Why A.class.getClassLoader() does not return the loader used by loader.loadClass("A")
在这个测试用例中,我们通过特定的 class 加载器实例加载 class A
,即 GwClassLoader
。但是,A.class.getClassLoader()
不检索那个 class 加载程序?这是测试用例:
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();
}
}
而且,这是 运行 class App
的输出:
Main: ClassLoaderGw@6d06d69c
A.<cinit>: sun.misc.Launcher$AppClassLoader@73d16e93
如何在 class A
的静态构造函数中获取 GwClassLoader
的实例?
这在the Javadoc中有描述:
Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:
- Invoke findLoadedClass(String) to check if the class has already been loaded.
- Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.
- Invoke the findClass(String) method to find the class.
您的 ClassLoader
将 sun.misc.Launcher$AppClassLoader1
作为父级,因为如 default constructor 的 Javadoc 中所述(它在 ClassLoaderGw
class, 因为没有明确的构造函数):
Creates a new class loader using the ClassLoader returned by the method getSystemClassLoader() as the parent class loader.
ClassLoaderGw
只是扩展了 ClassLoader
而没有覆盖任何方法。因此,它将遵循标准 loadClass
方法 (javadoc) 的策略......即首先委托给父 classloader。
在这种情况下,您的 A
class 在父 classloader 的 class 路径上,所以 that 是什么会加载它。
拼图的最后一块是 getClassLoader()
returns classloader 实际上 加载了 class,不是您要求进行加载的 classloader。
How can I get the instance of GwClassLoader inside the static constructor of the class A?
基本上,您不能...除非 GwClassloader
负责加载 class A
。
你能让它工作吗?嗯...如果您使用不同的 class 加载策略,您可以。可能是。如果 GwClassloader
能够找到 A
的字节码并调用 defineClass
本身,那么它将成为 A
的 class 加载器。
但是,您需要担心 class A
也可能被父 classloader 加载的可能性。如果发生这种情况,您可能同时存在两种不同的 A
类型。这可能会导致 class 在意想不到的地方出现异常。
在这个测试用例中,我们通过特定的 class 加载器实例加载 class A
,即 GwClassLoader
。但是,A.class.getClassLoader()
不检索那个 class 加载程序?这是测试用例:
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();
}
}
而且,这是 运行 class App
的输出:
Main: ClassLoaderGw@6d06d69c
A.<cinit>: sun.misc.Launcher$AppClassLoader@73d16e93
如何在 class A
的静态构造函数中获取 GwClassLoader
的实例?
这在the Javadoc中有描述:
Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:
- Invoke findLoadedClass(String) to check if the class has already been loaded.
- Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.
- Invoke the findClass(String) method to find the class.
您的 ClassLoader
将 sun.misc.Launcher$AppClassLoader1
作为父级,因为如 default constructor 的 Javadoc 中所述(它在 ClassLoaderGw
class, 因为没有明确的构造函数):
Creates a new class loader using the ClassLoader returned by the method getSystemClassLoader() as the parent class loader.
ClassLoaderGw
只是扩展了 ClassLoader
而没有覆盖任何方法。因此,它将遵循标准 loadClass
方法 (javadoc) 的策略......即首先委托给父 classloader。
在这种情况下,您的 A
class 在父 classloader 的 class 路径上,所以 that 是什么会加载它。
拼图的最后一块是 getClassLoader()
returns classloader 实际上 加载了 class,不是您要求进行加载的 classloader。
How can I get the instance of GwClassLoader inside the static constructor of the class A?
基本上,您不能...除非 GwClassloader
负责加载 class A
。
你能让它工作吗?嗯...如果您使用不同的 class 加载策略,您可以。可能是。如果 GwClassloader
能够找到 A
的字节码并调用 defineClass
本身,那么它将成为 A
的 class 加载器。
但是,您需要担心 class A
也可能被父 classloader 加载的可能性。如果发生这种情况,您可能同时存在两种不同的 A
类型。这可能会导致 class 在意想不到的地方出现异常。