构造块在字段显式初始化之后、构造方法体之前执行,按源码声明顺序与实例变量赋值交替进行;可访问已声明的本类及父类实例成员,但不可前向引用未声明字段,也不支持super()或this()调用。

构造块在 Java 属性初始化链中,处于字段显式初始化之后、构造方法体之前的位置,但它的实际执行时机还取决于它在类中声明的顺序——它和实例变量的显式赋值语句属于同一层级,按源码从上到下的顺序依次执行。
构造块与字段赋值的相对顺序决定最终值
Java 对实例成员的初始化不是按“类型”分组执行,而是严格按声明顺序逐行展开。构造块本质上是插入到每个构造方法开头的一段前置逻辑,但它参与的是整个实例初始化序列:
- 所有实例变量先被赋予默认值(如 int → 0,Object → null)
- 接着按源码顺序,依次执行:已声明的实例变量显式赋值 → 构造块 → 后续变量显式赋值 → 更多构造块
- 最后才进入构造方法体
例如:
class Example {
{ value = 200; } // 构造块1
int value = 100; // 显式赋值(覆盖上面)
{ value = 300; } // 构造块2(再次覆盖)
}
new Example() 后,value = 300。因为三个动作按序执行,后赋值者生效。
立即学习“Java免费学习笔记(深入)”;
构造块能访问什么?不能访问什么?
构造块运行时,对象内存已分配,this 可用,父类构造已完成,所以它可以安全操作当前类的实例字段和方法:
- ✅ 可读写本类 public/protected/default 实例变量
- ✅ 可调用本类或父类的实例方法(但需注意:若该方法被子类重写,此时子类字段尚未初始化,可能返回默认值)
- ❌ 不能访问在它之后才声明的字段(编译报错:“illegal forward reference”)
- ❌ 不能使用 super() 或 this() —— 那是构造方法首行的专属语法
它和构造方法分工明确,不可替代
构造块不接收参数,也不区分调用路径,因此它只适合做所有对象共有的、无差异化前提的初始化工作:
- 统一设置日志标记、状态标志位、资源预分配句柄
- 为多个构造方法共用的字段提供默认值(比在每个构造方法里重复写更可靠)
- 执行基础校验(如检查关键字段是否为 null),但复杂业务逻辑仍应留在构造方法中
而构造方法负责根据参数定制行为,比如设置 name/age、触发回调、启动线程等——这些不适合塞进构造块。
在继承链中,它始终紧贴父类构造完成之后
每次 new 子类对象时,构造块的执行嵌套在完整的继承初始化流程中:
- 父类实例变量赋值 → 父类构造块 → 父类构造方法
- 子类实例变量赋值 → 子类构造块 → 子类构造方法
这意味着子类构造块可以安全访问父类的 public/protected 实例字段,但无法访问父类 private 字段,作用域限制比执行顺序更刚性。


















