请描述 Java 中类的加载过程,包括加载、连接(验证、准备、解析)和初始化各阶段的主要职责与执行顺序。
考察说明
考查对 JVM 类加载机制各阶段职责和顺序的掌握,以及理解类加载与初始化的时机。
回答思路
- 【回答框架 1】类加载过程分为加载、连接、初始化三个阶段,其中连接又细分为验证、准备、解析。加载阶段由类加载器读取类的二进制字节流,并在堆中生成对应的 Class 对象。
- 【回答框架 2】验证阶段确保字节流符合 JVM 规范且不危害虚拟机安全;准备阶段为类变量分配内存并设置零值,静态常量在此阶段直接赋值为编译期常量。
- 【回答框架 3】解析阶段将符号引用替换为直接引用,包括类、接口、字段和方法等的解析;解析可延迟到使用前,但某些场景如静态方法调用必须解析。
- 【回答框架 4】初始化阶段执行类构造器 <clinit> 方法,为静态变量赋予程序员指定的初始值。主动使用场景如 new、访问静态字段、调用静态方法、反射、初始化子类等会触发初始化,而被动引用如引用父类静态字段不会触发子类初始化。
- 【关键点 1】加载、验证、准备、解析、初始化是类加载的标准流程,解析不一定在初始化前完成。
- 【关键点 2】加载阶段生成 Class 对象,准备阶段分配静态变量内存并置零值,初始化时执行 <clinit> 赋真实初值。
- 【关键点 3】主动引用触发初始化,被动引用如通过子类引用父类静态字段不触发子类初始化。
- 【易错点 1】混淆准备与初始化,误认为准备阶段即赋实际初值,实际是零值。
- 【易错点 2】误以为常量池中的静态常量在初始化时才赋值,实际编译期已写入常量池,准备阶段即可赋好。
- 【易错点 3】错误认为任何类的引用都会触发初始化,而忽略被动引用的例外情况。