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.Collection
,Set
List
等课程。那么为什么Bootstrap类加载器正在加载它们。这是JVM规范要求的方式或Bootstrap类加载器如何决定加载哪些类?
修改
另一方面:
即使您尝试运行不存在的类,程序也会以ClassNotFoundException
结束,但不会加载前面提到的所有类。所以这些类只是在调用JVM时加载!所以JVM默认加载一组类,但管理这种行为的是什么?
答案 0 :(得分:3)
Class
是java.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类加载器:
VM's built-in classloader
java.
类,即以java开头的类。不能被其他任何东西加载(这是安全模型的一部分)object.getClass().getClassLoader()
返回null
,因为bootstrap类加载器通常位于本机/ C代码(JVM的一部分)中,即它不是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