库存JDK类和“null”ClassLoader?
嗨伙计们:我试图通过查看一些动态创建的组件的ClassLoader
来调试一个非常奇怪的类错误。 ClassLoader
是我从未玩过的东西 – 我很惊讶标准的JDK类有空的类加载器实例。
有人可以根据我试图打印的加载器的类来解释这个简单主方法的输出,并且更一般地说 –
-
ClassLoader
在JVM上运行的方式 - 我们如何使用
ClassLoader
调试缺少的类。
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
getClassLoader()
的javadoc说
返回类的类加载器。 某些实现可能使用null来表示引导类加载器。 如果此类由引导类加载器加载,则此方法将在此类实现中返回null。
所以,至少可以解释为什么你得到那个结果。 但它并没有解释为什么实现者决定这样做。
编辑:测试后,我将自己的类添加到bootclasspath,然后它们也显示为null类加载器。
bootstrap类的类加载器为null,它不是java类。
不要误认为类路径中找到的类和引导加载程序加载的类。 后者负责通常在rt.jar中找到的核心JDK类。 它是一个本机类加载器,因此没有参考。
类路径上的类由System类加载器加载,并且可以通过property指定类的类。
此外,null类加载器被认为是一个安全问题,并且存在基于具有null类加载器的调用者类的检查。
这是它的工作原理。 每当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。