According to the JVM spec,启动类加载的类加载器]被JVM记录为initiating class loader。此外,根据ClassLoader#findLoadedClass()的JavaDoc,方法
返回具有给定二进制名称的类如果此虚拟加载器已由Java虚拟机记录为启动加载器具有该二进制名称的类。
(重点是我的)
考虑一个简单的类加载器
class SimpleClassLoader extends ClassLoader {
void foo() {
System.err.println(loadClass("foo.Bar"));
System.err.println(findLoadedClass("foo.Bar"));
}
}
鉴于foo.Bar
实际上存在于类路径中,new SimpleClassLoader().foo()
打印
class foo.Bar
null
根据上述原因,SimpleClassLoader
应该是启动类加载器,findLoadedClass("foo.Bar")
应该只是返回成功加载的类。
现在考虑第二个版本:
class SimpleClassLoader2 extends ClassLoader {
SimpleClassLoader2() {
super(null); // disables delegation
}
protected Class<?> findClass(String name) {
try {
byte[] b = IOUtils.toByteArray(new FileInputStream("path/to/foo/Bar.class"));
return defineClass("foo.Bar", b, 0, b.length);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
void foo() {
System.err.println(loadClass("foo.Bar"));
System.err.println(findLoadedClass("foo.Bar"));
}
}
这使SimpleClassLoader2
既是foo.Bar
的启动类,也是定义的类加载器。确实,现在new SimpleClassLoader2().foo()
打印出所需的
class foo.Bar
class foo.Bar
所以文档是错误的,或者我不明白为什么SimpleClassLoader
不被视为foo.Bar
的初始类加载器。有人可以对此有所帮助吗?