传统set+new写法与Builder写法的区别
这段代码:
Employee employee = Employee.builder().status(status).id(id).build();
和传统的
Employee employee = new Employee();
employee.setStatus(status);
employee.setId(id);
功能上完全一样:最终都得到一个新的 Employee
对象,并把 status
和 id
两个字段赋好值。
区别主要体现在 写法、可读性、可维护性 上。
- 语法层面
-
builder 写法
‑ 依赖 Lombok 的@Builder
(或手写 Builder 类)。
‑ 链式调用,像拼积木一样把字段一次性“流式”地拼完,再build()
。 -
传统写法
‑ 先new
,再逐个setXxx()
,代码呈“命令式”两步走。
- 优点对比
维度 | Builder | new + set |
---|---|---|
可读性 | 高:一眼看出所有赋值字段 | 低:set 调用散落在多行,容易遗漏 |
不可变对象 | 天然支持:字段可设为 final ,只在 build() 时一次性写入 | 难:必须手写全参构造,且后续仍可 set |
可选参数/默认值 | 优雅:想设几个就链几个,未设置的走默认值 | 麻烦:要么重载 N 个构造,要么不断 set |
线程安全 | build 完就是不可变,后续无并发修改风险 | set 调用可被并发篡改 |
样板代码量 | 一个 @Builder 注解搞定 | 需要大量 set/get 或重载构造 |
- 运行层面
- 性能:两者都只是一次对象创建 + 两次字段赋值,差别微乎其微。
- 字节码:builder 会额外生成一个静态内部类
EmployeeBuilder
,占用几 KB 内存,对应用整体影响可忽略。 - 空指针/合法性校验:builder 可在
build()
方法里集中校验;传统写法需自己再写校验逻辑。
- 何时用哪种?
- 简单 POJO、字段很少、确定可变 → new + set 足够。
- 字段较多(>4 个)、希望不可变、需要默认值、链式调用 → builder 更好。
- 需要与 JSON/YAML 映射框架(Jackson、SnakeYAML)配合 → builder 同样方便,它们都支持无参构造 + setter,也支持 builder 模式。
一句话总结:
builder 写法是语法糖,让你“像构造器一样一次性赋值”,既保持了可读性,又天然支持不可变和可选字段,而传统 new + set 更直观但啰嗦、易错。