库存JDK类和“null”ClassLoader?

时间:2011-12-09 19:23:55

标签: java classloader

大家好:我试图通过查看动态创建的组件的ClassLoader来调试一个非常奇怪的类错误。 ClassLoader是我从未玩过的东西 - 我很惊讶标准的JDK类有 null 类加载器实例。

有人可以根据我试图打印的加载器的类来解释这个简单主方法的输出,并且更一般地说 -

  1. ClassLoader在JVM上的工作方式和
  2. 我们如何使用ClassLoader来调试缺失的类。
  3. public class MyClass {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    
            System.out.println(relfect.MyClass.class.getClassLoader());
            System.out.println(String.class.getClassLoader());
            System.out.println(ArrayList.class.getClassLoader());
            System.out.println(JButton.class.getClassLoader());
            System.out.println(System.class.getClassLoader());
    
            Boolean b = new Boolean(true);
            System.out.println(b.getClass().getClassLoader());
    
        }
    
    }
    

    输出

    sun.misc.Launcher$AppClassLoader@1f7182c1
    null
    null
    null
    null
    null
    

3 个答案:

答案 0 :(得分:19)

getClassLoader() 的javadoc说

  

返回类的类加载器。某些实现可能使用null来表示引导类加载器。如果此类由引导类加载器加载,则此方法将在此类实现中返回null。

所以,至少可以解释为什么你会得到那个结果。但这并没有解释为什么实现者决定这样做。

编辑: 在测试将我自己的类添加到bootclasspath之后,它们也显示为null类加载器。

答案 1 :(得分:2)

bootstrap类的类加载器为null,它不是java类。

不要误认为找到类路径的类和引导加载程序加载的类。后者负责通常在rt.jar中找到的核心JDK类。它是一个原生的类加载器,因此没有参考。

类路径上的类由System类加载器加载,并且可以通过属性指定类的类。

此外,null类加载器被认为是一个安全问题,并且存在基于具有null类加载器的调用者类的检查。

答案 2 :(得分:1)

这是它的工作原理。每当JVM尝试加载任何类时,都会检查以下条件。

如果从Bootstrap ClassPath加载Class,即; jdk \ jre \ lib \ rt.jar,将调用BootStrap ClassLoader。

如果从Extension Classpath加载Class,即; jdk \ jre \ lib \ ext * .jar,将调用Extension ClassLoader。

如果从Application ClassPath加载Class,即;在Environment Variable中指定,调用Application ClassLoader。

由于Bootstrap ClassLoader没有在java中实现,所以它要么用c或c ++实现,所以没有引用它就是它返回null的原因。但Extension和Application类Loader是用java编写的,因此您将获得sun.misc.Launcher$ExtClassLoader@someHexValue和sun.misc.Launcher $ AppClassLoader@someHexValue的引用。

所以,如果你做类似这样的System.out.println(String.class.getClassLoader())你会得到null,因为这个类是由BootStrap ClassLoader调用的,另一方面如果你做同样的事情在Ext或App Class路径中的一个类,你将分别获得$ ExtClassLoader @ someHexValue和sun.misc.Launcher $ AppClassLoader@someHexValue。