极高 进阶
类加载过程#
一句话答案#
类加载五阶段:加载(读字节码)→验证→准备(静态变量零值)→解析(符号→直接引用)→初始化(执行
)。
核心要点
加载: 读取字节码→生成Class对象
验证: 格式/语义/字节码/符号引用验证
准备: 静态变量分配内存并赋零值
解析: 符号引用→直接引用
初始化: 执行
面试回答(2分钟版)
类加载过程分为五个阶段,口诀是”加验准解初”。加载阶段通过类的全限定名获取字节码二进制流,在方法区生成运行时数据结构并在堆中创建 Class 对象作为访问入口。验证阶段对文件格式、语义、字节码和符号引用做安全校验,确保不会危害 JVM。准备阶段为类的静态变量在方法区分配内存并赋零值,比如 static int a = 10 在这个阶段 a 的值是 0 而不是 10。解析阶段把常量池中的符号引用替换为直接引用,即把类名、方法名等字符串解析为内存地址。初始化阶段才真正执行类的 clinit 方法,按代码顺序执行静态变量赋值和 static 代码块,此时 a 才变成 10。触发初始化的时机包括 new 实例化对象、调用静态方法、反射调用、子类初始化触发父类初始化以及 Main 主类启动。注意引用类的常量字段或通过数组定义引用类不会触发初始化,这属于被动引用。
追问与易错
追问方向:
- “准备阶段和初始化阶段的区别?”→ 准备赋零值,初始化赋真正的值
- “什么时候触发类的初始化?”→ new/静态方法/反射/子类初始化触发父类/Main类
- “为什么有些类不会被初始化?”→ 引用常量/数组类型/被动引用
易错点:
- ❌ “加载就是初始化”——加载只是读字节码,初始化才执行
- ❌ 混淆”准备阶段”和”初始化阶段”——static int a = 10 在准备阶段是 0,初始化才是 10