Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/java/jvm/类加载过程.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
对于初始化阶段,虚拟机严格规范了有且只有 5 种情况下,必须对类进行初始化(只有主动去使用类才会初始化类):

1. 当遇到 `new` 、 `getstatic`、`putstatic` 或 `invokestatic` 这 4 条直接码指令时,比如 `new` 一个类,读取一个静态字段(未被 final 修饰)、或调用一个类的静态方法时。
- 当 jvm 执行 new 指令时会初始化类。即当程序创建一个类的实例对象。
- 当 jvm 执行 getstatic 指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。
- 当 jvm 执行 putstatic 指令时会初始化类。即程序给类的静态变量赋值。
- 当 jvm 执行 invokestatic 指令时会初始化类。即程序调用类的静态方法。
2. 使用 `java.lang.reflect` 包的方法对类进行反射调用时如 Class.forname("..."), newInstance()等等。如果类没初始化,需要触发其初始化。
- 当 jvm 执行 `new` 指令时会初始化类。即当程序创建一个类的实例对象。
- 当 jvm 执行 `getstatic` 指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。
- 当 jvm 执行 `putstatic` 指令时会初始化类。即程序给类的静态变量赋值。
- 当 jvm 执行 `invokestatic` 指令时会初始化类。即程序调用类的静态方法。
2. 使用 `java.lang.reflect` 包的方法对类进行反射调用时如 `Class.forname("...")`, `newInstance()` 等等。如果类没初始化,需要触发其初始化。
3. 初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。
4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。
5. MethodHandle 和 VarHandle 可以看作是轻量级的反射调用机制,而要想使用这 2 个调用,
就必须先使用 findStaticVarHandle 来初始化要调用的类。
4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 `main` 方法的那个类),虚拟机会先初始化这个类。
5. `MethodHandle``VarHandle` 可以看作是轻量级的反射调用机制,而要想使用这 2 个调用,
就必须先使用 `findStaticVarHandle` 来初始化要调用的类。
6. **「补充,来自[issue745](https://github.com/Snailclimb/JavaGuide/issues/745)」** 当一个接口中定义了 JDK8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

## 卸载
Expand Down