Bootstrap类加载器加载的类

时间:2013-12-27 07:16:47

标签: java classloader

this post引发了这个问题。当运行如下的简单程序时

public class Sample
{
    public static void main(String[] args)
    {
    }
}

使用选项-versbose:class,它在加载此类之前列出了一堆类

[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]

我的问题是,

我的程序从不需要java.util.CollectionSet List等课程。那么为什么Bootstrap类加载器正在加载它们。这是JVM规范要求的方式或Bootstrap类加载器如何决定加载哪些类?

修改

另一方面:

即使您尝试运行不存在的类,程序也会以ClassNotFoundException结束,但不会加载前面提到的所有类。所以这些类只是在调用JVM时加载!所以JVM默认加载一组类,但管理这种行为的是什么

3 个答案:

答案 0 :(得分:3)

Classjava.lang包的一部分,因此引导类加载器会将其选中以进行加载,但Class本身需要一些依赖的框架类,如List或{ {1}},所以它们也被加载了。

如果您在JDK中看到Set的代码,您将找到以下导入

Class

import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.LinkedHashSet; import java.util.Set; import java.util.Map; import java.util.HashMap; 来源内部使用Class,因此需要加载。

答案 1 :(得分:2)

似乎有些误解了bootstrap类加载器:

  • 它解决了鸡/蛋的问题:拥有一个你需要的类加载器实例 - 很多类,包括对象/类/集合/ io / nio等等。
  • a.k.a。 VM's built-in classloader
  • 它加载所有java.类,即以java开头的类。不能被其他任何东西加载(这是安全模型的一部分)
  • 实际上,bootstap类加载器加载了JRE提供的所有类(例如来自rt.jar的所有类),尽管如果包没有启动w / java。可以通过应用程序类加载器加载它
  • object.getClass().getClassLoader()返回null,因为bootstrap类加载器通常位于本机/ C代码(JVM的一部分)中,即它不是java类(因为它不能由本身,见上面的鸡肉/鸡蛋)
  • 它不是任何其他类加载器的直接父级,ClassLoader.getParent()不会返回它。
  • 没有正式的直接方式来调用它的方法(因为它不作为java类存在),

现在回答直接问题:"是什么决定了这种行为?" - 当第一次尝试通过Class.forName'加载课程时,通常是当前班级' classloader要求自己的父母这样做。 Bootstrap类加载器被认为是系统类加载器的父级(加载主类)。如果引导类加载器已经加载了当前类,则它使用VM来解析所需加载的类。

Last - java中的类总是在需要时动态加载,每次尝试调用方法时 - 它都需要从常量池中获取必须解析的完全限定类名。这种行为独立于班级'类加载器。因此,当JVM实现第一类时,球开始滚动。

答案 2 :(得分:1)

JRE可能会延迟加载,即只在需要时才加载类。

但是,在访问主类之前,JRE已经在执行许多其他java代码,特别是sun.misc.Launcher。这就是为什么在课前加载很多课程的原因。


一般来说,JRE可自行决定随时加载喜欢的任何课程。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.2

  

实现可以解析来自很早就链接的类或接口的符号引用,甚至可以递归地解析来自进一步引用的类和接口的所有符号引用。

     

实现可以选择仅在主动使用时解析符号引用;对所有符号引用一致使用此策略将代表“最懒惰”的解决方案。

请注意,类的初始化在严格指定的时刻发生;没有“急切”的初始化 - http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1