推荐答案
Java 类的加载过程主要分为以下三个步骤:
加载(Loading):通过类的全限定名获取类的二进制字节流,并将这些字节流转换为方法区中的运行时数据结构,最后在堆中生成一个代表该类的
java.lang.Class对象。链接(Linking):
- 验证(Verification):确保加载的类符合 JVM 规范,防止恶意代码的破坏。
- 准备(Preparation):为类的静态变量分配内存并设置默认初始值。
- 解析(Resolution):将类、方法、字段等符号引用转换为直接引用。
初始化(Initialization):执行类的静态初始化块和静态变量的赋值操作,这是类加载的最后一步。
本题详细解读
1. 加载(Loading)
加载是类加载过程的第一个阶段,主要完成以下工作:
- 通过类的全限定名(如
java.lang.String)获取类的二进制字节流。 - 将字节流所代表的静态存储结构转换为方法区的运行时数据结构。
- 在堆中生成一个代表该类的
java.lang.Class对象,作为方法区中这些数据的访问入口。
2. 链接(Linking)
链接阶段分为三个子阶段:
2.1 验证(Verification)
验证阶段确保加载的类符合 JVM 规范,防止恶意代码的破坏。验证的内容包括:
- 文件格式验证:确保字节流符合 Class 文件格式规范。
- 元数据验证:对类的元数据信息进行语义校验,确保符合 Java 语言规范。
- 字节码验证:通过数据流和控制流分析,确保程序语义是合法的。
- 符号引用验证:确保符号引用能够正确解析。
2.2 准备(Preparation)
准备阶段为类的静态变量分配内存并设置默认初始值。需要注意的是,这里的初始值通常是数据类型的默认值(如 0、null 等),而不是代码中显式赋予的值。
2.3 解析(Resolution)
解析阶段将类、方法、字段等符号引用转换为直接引用。符号引用是一组符号来描述所引用的目标,而直接引用则是直接指向目标的指针、相对偏移量或间接定位到目标的句柄。
3. 初始化(Initialization)
初始化阶段是类加载过程的最后一步,主要完成以下工作:
- 执行类的静态初始化块(
static {}块)。 - 为静态变量赋予代码中显式指定的初始值。
初始化阶段是类加载过程中最核心的部分,也是开发人员最常接触的部分。JVM 保证类的初始化在多线程环境下是线程安全的。