构造代码块是实例级别初始化机制,每次new对象时执行一次,位于类体中、方法外,用{}包裹且无static,JVM保证其在父类构造返回后、本类构造主体前按源码顺序执行。

构造代码块适合在每个对象创建时、构造方法执行前,统一处理实例变量或执行通用初始化逻辑。它不是“类级别”的一次性操作,而是“实例级别”的必经步骤,天然适配多构造函数场景。
构造代码块的核心定位
它写在类体中、方法外,用一对花括号 {} 包裹,不加 static。JVM 保证:每次调用任意构造方法前,都会按源码顺序执行该类所有构造代码块,且在父类构造方法返回之后、当前类构造方法主体开始之前运行。
- 每次 new 一个对象,它就执行一次
- 可访问 this、实例变量和静态成员
- 多个构造代码块按定义顺序依次执行
- 不能包含 return 或抛出受检异常(除非在 try-catch 内)
统一处理实例变量的典型写法
把多个构造函数共用的初始化逻辑(如默认值计算、状态预设、资源轻量准备)提取到构造代码块里,避免重复代码。
例如,一个用户类需确保每次创建时 status 默认为 "ACTIVE",createTime 自动设为当前时间,且 id 按规则生成:
public class User {
private String id;
private String status;
private LocalDateTime createTime;
// 构造代码块:所有实例共享的初始化入口
{
status = "ACTIVE";
createTime = LocalDateTime.now();
id = "USR_" + System.nanoTime(); // 简单示例,实际可用 UUID 或序列器
}
public User() {
// 无参构造:自动触发上面的块
}
public User(String name) {
// 有参构造:同样先执行块,再进入本体
this.name = name;
}
private String name;
}
无论调用哪个构造函数,status、createTime、id 都已就绪,无需在每个构造方法里重复赋值。
配合字段初始化与执行顺序控制
构造代码块和字段初始化表达式(如 private int count = getCount();)都属于“实例初始化阶段”,它们按源码文本顺序混合执行。
- 字段声明在前 → 初始化表达式先执行
- 构造代码块在前 → 块先执行
- 若块中访问尚未声明的字段,会报“非法前向引用”编译错误
所以推荐把字段声明放在构造代码块之前,或确保块内只访问已声明/已初始化的成员。例如:
public class Order {
private final long orderId = generateId(); // 字段初始化优先于块
private String remark;
{
// 此处可安全使用 orderId
remark = "ORDER_" + orderId;
}
private long generateId() {
return System.currentTimeMillis();
}
}
实战中要注意的边界情况
构造代码块看似简单,但几个细节容易引发问题:
- 不要在块中调用可能被子类重写的方法(如
this.init()),此时子类字段还未初始化,易出现NullPointerException - 避免耗时操作(如 I/O、网络请求),它会拖慢每次对象创建,影响性能敏感路径
- 不能替代构造函数做参数校验或复杂分支逻辑——它没有参数,也不支持
if-else控制流来区分不同构造路径 - 若需差异化初始化,仍应由各构造函数自行处理,块只负责“交集部分”
不复杂但容易忽略。

















