Java 类的加载过程是什么?

· 约 2 分钟读完 · 第 107 / 274 章

推荐答案

Java 类的加载过程主要分为以下三个步骤:

  1. 加载(Loading):通过类的全限定名获取类的二进制字节流,并将这些字节流转换为方法区中的运行时数据结构,最后在堆中生成一个代表该类的 java.lang.Class 对象。

  2. 链接(Linking):

    • 验证(Verification):确保加载的类符合 JVM 规范,防止恶意代码的破坏。
    • 准备(Preparation):为类的静态变量分配内存并设置默认初始值。
    • 解析(Resolution):将类、方法、字段等符号引用转换为直接引用。
  3. 初始化(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 保证类的初始化在多线程环境下是线程安全的。