java代码块执行顺序由jvm类加载和对象创建两阶段严格驱动:先类初始化(静态变量默认值→静态赋值与静态块,父类优先),再实例初始化(实例变量默认值→实例赋值与实例块→构造器,自顶向下进入、自底向上返回)。

Java 中代码块执行顺序不是靠记忆口诀,而是由 JVM 在类加载和对象创建两个阶段严格控制的。规范对象的实例化路径,关键在于把初始化逻辑放在正确的位置:静态部分管“类”,实例部分管“对象”,父类永远先于子类完成准备。
静态代码块与静态变量:只跑一次,决定类就绪状态
静态成员在类首次被主动使用(如 new 实例、调用静态方法、访问静态字段)时触发初始化。JVM 将所有静态变量显式赋值语句和 static {} 块按源码从上到下合并进一个
- 父类静态部分一定先执行,子类静态部分在其后,且整个生命周期仅一次
- 准备阶段只设默认值(0 / null / false),真正赋值和逻辑执行都在
阶段 - public static final 基本类型常量(如 MAX = 100)是编译期常量,不触发类初始化
- 避免在静态块中调用可能被子类重写的方法——此时子类尚未加载,可能读到未初始化值
实例代码块与字段初始化:每次 new 都走通路
实例代码块(即不带 static 的 {})和字段声明处的初始化(如 String name = "Tom";)地位等同,都属于“实例初始化阶段”。它们会被编译器自动插入到每个构造方法体的最开头,在 super() 返回之后、构造方法体开始之前执行。
- 多个实例块按源码顺序依次执行,就像普通语句一样逐行运行
- 可安全使用 this 和所有已声明的实例字段,但不能调用可能被子类重写的方法(子类字段尚未初始化)
- 即使构造器里有 this() 调用其他重载构造器,实例块也只执行一次(在最终进入的那个构造器入口)
- 字段初始化语句和实例块混合时,谁写在前面谁先执行
构造器:对象成型的最后一环,负责差异化逻辑
构造器不是初始化起点,而是终点。它在所有实例块执行完毕后才开始运行,作用是完成对象特有行为:参数校验、资源分配、业务规则设定等。
- 若未显式写 super() 或 this(),编译器默认插入 super()
- super() 触发父类构造流程,所以父类构造器总在子类之前完成
- 子类构造器体中可访问已初始化的父类字段,但不能依赖尚未执行的子类实例块或字段初始化
- 不要在构造器中启动线程或发布 this 引用——此时对象可能还未完全构造好
父子类混合场景下的完整流水线
执行 new Child() 时,实际经历两轮初始化:先类加载(静态),再对象创建(实例)。最终顺序固定为:
- 父类静态变量默认值 → 父类静态赋值 + 静态块(从上到下)
- 子类静态变量默认值 → 子类静态赋值 + 静态块(从上到下)
- 父类实例变量默认值 → 父类实例赋值 + 实例块(从上到下)→ 父类构造器体
- 子类实例变量默认值 → 子类实例赋值 + 实例块(从上到下)→ 子类构造器体
这个顺序不可跳过、不可倒置,是 JVM 规范保障的确定性行为。用日志在每个环节打点,比凭经验猜测更可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











