构造代码块在每次创建对象时执行,且一定先于构造方法运行;它不依赖构造函数参数,是所有实例共用的初始化入口,执行顺序为:静态代码块→构造代码块→构造方法,继承时按父类静态→子类静态→父类构造块→父类构造→子类构造块→子类构造执行。

构造代码块在每次创建对象时执行,且一定先于构造方法运行。它不依赖构造函数的参数或重载形式,是所有实例共用的初始化入口。
单个类中三者的执行顺序
类加载后首次 new 实例时,按以下固定顺序执行:
- 静态代码块(只执行一次,类加载时)
- 构造代码块(每次 new 都执行,紧接在父类构造之后、本类构造之前)
- 构造方法(最后执行,完成对象专属逻辑)
例如定义一个类:
static { System.out.println("静态块"); }
{ System.out.println("构造块"); }
public Demo() { System.out.println("构造方法"); }
调用 new Demo() 输出顺序就是:静态块 → 构造块 → 构造方法。
继承场景下的完整链路
当存在父子类继承时,执行流是一条不可跳过的单向流水线:
- 父类静态代码块 → 子类静态代码块(类加载阶段,仅首次触发)
- 父类构造代码块 → 父类构造方法
- 子类构造代码块 → 子类构造方法(注意:成员变量初始化语句如 Rmb r = new Rmb(); 就插在此处,紧挨构造块)
这个顺序确保父类状态先就绪,子类才能安全访问和扩展;任何试图绕过或打乱该顺序的写法(如把 super() 放在构造方法中间)都会被编译器拒绝。
立即学习“Java免费学习笔记(深入)”;
构造块 vs 构造方法的核心区别
构造代码块不是方法,没有名称、不接收参数、不能显式调用——它由 JVM 自动插入到每个构造方法的开头(在 super() 或 this() 之后、其余代码之前)。
- 构造块适合放通用初始化逻辑(比如日志、默认赋值、资源预设)
- 构造方法负责差异化初始化(比如根据参数设置不同状态、校验输入)
- 多个构造方法共用同一套构造块,避免重复代码
例如 Person 类中声明 { name = "unknown"; },无论调用无参还是有参构造,name 都会先被设为 unknown,再被构造方法覆盖或保留。
实战验证技巧
快速确认执行顺序,只需在每个关键位置加一行打印:
- 每个静态块里输出 “X static”
- 每个构造块里输出 “X init block”
- 每个构造方法里输出 “X ctor”
运行 new Child(),控制台输出就是对象诞生的真实时间轴。第二次 new 同一类时,静态部分不再出现——这正说明静态属于类,构造块和构造方法才真正属于对象。


















