在此测试用例中,我们通过特定的类加载器实例加载类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();
}
}
而且,这是运行类App
:
Main: ClassLoaderGw@6d06d69c
A.<cinit>: sun.misc.Launcher$AppClassLoader@73d16e93
如何在类GwClassLoader
的静态构造函数中获取A
的实例?
答案 0 :(得分:2)
ClassLoaderGw
只是扩展ClassLoader
而不会覆盖任何方法。因此,它将遵循标准loadClass
方法(javadoc)的策略... ...首先委托给父类加载器。
在这种情况下,您的A
类位于父类加载器的类路径中,因此 将加载它。
最后一个难题是getClassLoader()
返回实际加载类的类加载器,而不是您要求加载的类加载器。
如何在A类的静态构造函数中获取GwClassLoader的实例?
基本上,您不能......除非GwClassloader
负责加载课程A
。
你可以使运作吗?好吧......如果你使用了不同的类加载策略,你可以。也许。如果GwClassloader
能够找到A
的字节码并且自己调用defineClass
,那么它将成为A
的类加载器。
但是,您需要担心父类加载器也可能加载类A
。如果发生这种情况,您可以同时存在两种不同的A
类型。这可能导致意外地点的类别转换异常。
答案 1 :(得分:1)
使用指定的二进制名称加载类。此方法的默认实现按以下顺序搜索类:
- 调用findLoadedClass(String)以检查该类是否已加载。
- 在父类加载器上调用loadClass方法。如果父级为null,则使用内置于虚拟机的类装入器。
- 调用findClass(String)方法以查找类。
您的ClassLoader
将sun.misc.Launcher$AppClassLoader1
作为父级,因为正如default constructor的Javadoc所述(在ClassLoaderGw
类中隐式调用,因为有import socket
import sys
from _thread import *
host = '127.0.0.1'
port = 6666
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.bind((host,port))
except socket.error as e:
print(str(e))
s.listen(5)
print ('waiting for clinet')
def threaded_client(conn):
k=1
conn.send(str.encode('Welcome You are connected'))
while True:
k=k+1
conn.send(str.encode('Loop',k))
while True:
conn, addr = s.accept()
print ('connected to : ' + addr[0] + str(addr[1]))
start_new_thread(threaded_client,(conn,))
类没有明确的构造函数):
使用方法getSystemClassLoader()返回的ClassLoader作为父类加载器创建一个新的类加载器。