java类生命周期为加载→验证→准备→解析→初始化→使用→卸载,其中前五阶段构成类加载过程;初始化仅由主动使用触发,执行静态变量显式赋值和static{}块,且遵循父类优先、文本顺序、静态先于实例等严格顺序。

类的生命周期和初始化顺序,关键在分清“什么时候开始加载”和“什么时候真正执行代码”。类不是一写完就进内存,也不是一声明就执行静态块;它按需推进,阶段分明,每一步都有明确触发条件和执行规则。
类生命周期的五个核心阶段
Java 类从磁盘到可用,经历加载 → 验证 → 准备 → 解析 → 初始化。其中:
-
加载:根据全限定名找到 .class 字节流(本地文件、JAR、网络、动态生成等),载入方法区,并在堆中创建一个
Class对象作为访问入口; - 验证:检查字节码是否合规,防止恶意或损坏的类破坏 JVM 安全;
-
准备:为
static变量分配内存并设默认值(如int设为 0,Object设为null),不执行任何 Java 代码; - 解析:把常量池里的符号引用(比如类名、方法名)转成内存中的直接地址,这个阶段可延迟到首次使用时;
-
初始化:真正运行
<clinit></clinit>方法——执行所有静态变量显式赋值(如static int x = 5;)和static{}块,且只执行一次。
哪些操作会真正触发初始化
只有“主动使用”才会启动初始化,被动引用(如声明变量、创建数组)不会触发静态块或赋值语句:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用
new创建该类或其子类的实例; - 访问该类的静态非常量字段(
public static int val = 10;会触发;但public static final int VAL = 100;编译期内联,不触发); - 调用该类的静态方法;
- 通过
Class.forName("X")反射加载(注意:ClassLoader.loadClass()只加载不初始化); - 初始化子类时,若父类未初始化,则先初始化父类;
- JVM 启动时指定的主类(含
main方法的类)。
初始化执行顺序有严格规则
一旦触发,JVM 按固定逻辑执行,不受编译器优化影响:
-
父类优先:先完成父类全部静态初始化(静态变量赋值 +
static{}),再轮到子类; - 静态先于实例:所有静态内容只执行一次,且在任何对象创建前完成;
-
文本顺序为准:同一类中,静态变量声明与
static{}块按源码从上到下依次执行; - 实例初始化每次 new 都走一遍:顺序是父类实例块 → 父类构造器 → 子类实例块 → 子类构造器,与静态初始化完全分离。
容易混淆的两个点
一是准备阶段和初始化阶段的区别:分配内存和设默认值在“准备”,赋具体值和执行静态块在“初始化”;二是子类引用父类静态字段时,只初始化父类,子类连自己的 static{} 都不会执行——这是 JVM “最小初始化”原则的体现,兼顾性能与语义严谨性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










