findLoadedClass()返回null

问题描述 投票:8回答:2

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的初始类加载器。有人可以对此有所帮助吗?

java jvm internals
2个回答
3
投票
© www.soinside.com 2019 - 2024. All rights reserved.