在 JVM(Java 虚拟机)中,一个类会在以下几种情况下被加载:
一、首次主动使用时
-
创建类的实例:
- 当使用
new
关键字创建一个类的对象时,JVM 会确保这个类已经被加载、链接和初始化。 - 例如:
MyClass obj = new MyClass();
在这个例子中,如果
MyClass
还没有被加载,JVM 会在执行这条语句时加载MyClass
。 - 当使用
-
调用静态方法:
- 当调用一个类的静态方法时,JVM 会先加载这个类。
- 例如:
MyClass.myStaticMethod();
如果
MyClass
在此之前没有被加载,JVM 会在调用这个静态方法时加载MyClass
。 -
访问静态字段:
- 当访问一个类的静态字段时,JVM 会加载这个类。
- 例如:
int value = MyClass.staticField;
如果
MyClass
还未被加载,JVM 会在访问这个静态字段时加载它。 -
使用反射:
- 当使用反射机制来访问一个类的方法、字段或构造函数时,JVM 会加载这个类。
- 例如:
Class<?> clazz = Class.forName("MyClass");
这条语句会导致 JVM 加载
MyClass
。
二、子类加载引发父类加载
-
加载子类:
- 当一个类的子类被加载时,JVM 会先加载这个子类的父类。
- 例如,如果有一个类
SubClass
继承自SuperClass
,当SubClass
被加载时,如果SuperClass
还没有被加载,JVM 会先加载SuperClass
。
-
接口实现类加载引发接口加载:
- 当一个类实现了一个接口时,在加载这个实现类时,如果接口还没有被加载,JVM 会先加载这个接口。
- 例如,如果有一个类
MyImplClass
实现了接口MyInterface
,当MyImplClass
被加载时,如果MyInterface
还没有被加载,JVM 会先加载MyInterface
。
三、特定的 JVM 启动参数指定
-
-XX:+TraceClassLoading
:- 使用这个参数可以让 JVM 在加载类时打印出日志信息,方便开发人员观察类的加载过程。
- 例如,在启动 Java 程序时可以使用以下命令:
java -XX:+TraceClassLoading MyProgram
-
其他启动参数:
- 还有一些其他的 JVM 启动参数可以影响类的加载行为,例如
-verbose:class
也可以打印类加载的信息。
- 还有一些其他的 JVM 启动参数可以影响类的加载行为,例如
总之,JVM 在需要使用一个类的时候会加载它,并且类的加载过程是由 JVM 自动管理的。了解类的加载时机对于理解 Java 程序的运行机制和性能优化非常重要。