Builder模式通过私有final字段、静态内部Builder类和原子化build()操作强化封装,杜绝非法中间态与外部篡改,使对象构建可控、不可变、校验集中。

Java 中封装通过 Builder 模式优化复杂对象构建,核心在于把“对象怎么创建”从类内部移出来,让产品类专注自身结构和行为,不被初始化逻辑拖累。它不是简单加个 set 方法,而是用明确步骤、可控顺序、不可变结果来守住封装边界。
封装痛点:传统方式如何破坏封装性
直接暴露字段或提供大量 public setter,等于把对象内部状态的控制权交给了调用方。比如一个 User 类有 8 个字段,若允许随意调用 setEmail()、setPhone(),就可能出现:
- 对象中途被部分修改,处于非法中间态(如邮箱已设但姓名为空)
- 字段校验逻辑散落在各处,甚至缺失
- final 字段无法在构造后保持不变,导致并发下状态不一致
Builder 如何加固封装
Builder 模式把初始化过程变成一次性的、受控的、原子的操作:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 产品类字段全部声明为 private final,彻底禁止外部修改
- Builder 类作为唯一合法入口,所有赋值都在其内部完成,校验逻辑可集中写在
build()方法中 - 构建完成后返回的是完全初始化、不可变的对象实例,调用方只能读,不能改
- Builder 自身可设计为静态内部类,与产品强绑定,不对外暴露实现细节
链式调用 + 不可变构建的典型写法
以 Order 为例,关键结构如下:
立即学习“Java免费学习笔记(深入)”;
public class Order {
private final String orderId;
private final List<Item> items;
private final String address;
private final PaymentMethod payment;
// 私有构造,仅 Builder 可访问
private Order(Builder builder) {
this.orderId = builder.orderId;
this.items = Collections.unmodifiableList(builder.items);
this.address = builder.address;
this.payment = builder.payment;
}
public static class Builder {
private String orderId;
private List<Item> items = new ArrayList<>();
private String address;
private PaymentMethod payment;
public Builder orderId(String orderId) {
this.orderId = orderId;
return this;
}
public Builder addItem(Item item) {
this.items.add(item);
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder payment(PaymentMethod payment) {
this.payment = payment;
return this;
}
public Order build() {
if (orderId == null || items.isEmpty() || address == null || payment == null) {
throw new IllegalStateException("Missing required fields");
}
return new Order(this);
}
}
}
调用时清晰、安全、不可逆:
Order order = new Order.Builder()
.orderId("ORD-2026-001")
.addItem(new Item("Laptop", 9999))
.address("Beijing, Chaoyang")
.payment(PaymentMethod.WECHAT)
.build(); // 此刻才真正生成不可变实例
封装增强的额外实践
- Builder 内部可做字段预处理(如 trim 空格、格式标准化),对外隐藏脏数据
- 支持默认值填充(如
status = "CREATED"),避免调用方重复设置 - Builder 方法可加注解(如
@NonNull),配合 Lombok 或 IDE 提前拦截空值 - 若需序列化兼容,Builder 类应实现
Serializable,且产品类避免使用匿名内部类引用

















