@Builder 是 Lombok 里最常用、也最易踩坑的注解——它一行实现《建造者模式》,但和"无参构造器""继承"配合时有一堆坑。这篇把 @Builder 讲透:基础用法、和构造器的配合、继承场景。
一、@Builder 是什么:一行实现建造者模式
对象字段多、参数可选时,new 一个个塞参数很痛苦。手写建造者模式要一大堆代码,@Builder 一行搞定:
@Builder
public class User {
private String name;
private int age;
private String email;
}
// 链式创建:字段多也不乱
User user = User.builder()
.name("BinMaker")
.age(18)
.email("bin@example.com")
.build();@Builder 自动生成:builder() 静态方法、build() 方法、每个字段的链式 setter(.name(...)、.age(...))。对应《建造者模式》的"链式调用",多参可选参对象的构造痛点被一行解决。
二、最大的坑:@Builder 会"吃掉"无参构造器
这是最常踩的坑。@Builder 生成的类,默认只有全参构造器(builder() 里要能拿到所有字段),没有无参构造器:
@Builder
public class User {
private String name;
}
// ❌ 编译/运行报错:没有无参构造器
new User();
// MyBatis/Jackson 反序列化(需要无参构造器)时会报错:
// 无法实例化 User,找不到无参构造器原因:@Builder 的类没有无参构造器,MyBatis 用反射 newInstance() 就炸了。
解决:@Builder 必须搭配构造器注解:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}三个注解的分工:
@Data:getter/setter/toString 等@Builder:建造者模式@NoArgsConstructor:给 MyBatis/Jackson 用(反序列化需要)@AllArgsConstructor:给@Builder用(builder 要能构造全字段对象)
口诀:@Builder 单独用必踩坑,@Builder + @NoArgsConstructor + @AllArgsConstructor 是标配。
三、继承的坑:@Builder 不支持继承,要用 @SuperBuilder
@Builder 生成的 builder 只包含当前类的字段,不含父类字段:
public class BaseEntity {
private Long id;
}
@Data
@Builder
public class User extends BaseEntity {
private String name;
}
// ❌ 编译报错:builder() 里没有 id 字段(父类字段不在 builder 里)
User.builder().id(1L).name("BinMaker").build();解决:用 @SuperBuilder(Lombok 1.18.2+):
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class BaseEntity {
private Long id;
}
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class User extends BaseEntity {
private String name;
}
// ✅ builder 包含父类 + 子类所有字段
User.builder().id(1L).name("BinMaker").build();口诀:没有继承用 @Builder,有继承用 @SuperBuilder(父类子类都标)。
四、@Builder 和 final 字段的冲突
@Builder 只能处理非 final 字段,类里有 final 字段会编译报错:
@Builder
public class User {
private final String name; // final 字段
private int age;
}
// ❌ 编译报错:@Builder 无法处理 final 字段原因:final 字段必须在构造器里赋值(不能通过 setter/builder 链式赋值)。所以有 final 字段的类别用 @Builder,用构造器或 @RequiredArgsConstructor。
五、小结
@Builder一行实现建造者模式,链式创建多字段对象- 最大坑:单独用会丢失无参构造器 → 配
@NoArgsConstructor+@AllArgsConstructor - 继承坑:
@Builder不含父类字段 → 用@SuperBuilder(父子都标) - final 坑:
@Builder的类不要有 final 字段
想了解 @Builder 背后的设计思想(为什么链式调用),看《建造者模式》;想了解 Lombok 其他常用注解,看《Lombok 详解:核心注解》。
