一、@Builder 是什么?
@Builder
是 Lombok 提供的一个非常实用的注解,它可以帮我们自动生成建造者模式(Builder Pattern)的代码。建造者模式是一种创建型设计模式,允许你逐步构建复杂对象,同时保持代码的可读性和可维护性。
二、@Builder 的核心功能
使用 @Builder
注解在类上后,Lombok 会自动为该类生成:
- 一个内部静态 Builder 类
- 与类属性对应的 Builder 方法
- build() 方法用于创建最终对象
- 通常还会生成 toString()、equals()、hashCode() 等方法(取决于其他注解)
三、基本使用示例
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class User {
private Long id;
private String name;
private int age;
private String email;
private String address;
}
生成的代码等价于:
public class User {
private Long id;
private String name;
private int age;
private String email;
private String address;
// 构造函数
private User(Long id, String name, int age, String email, String address) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
this.address = address;
}
// Getter和Setter方法(由@Data生成)
// 内部Builder类
public static class UserBuilder {
private Long id;
private String name;
private int age;
private String email;
private String address;
UserBuilder() {
}
// 链式调用方法
public UserBuilder id(Long id) {
this.id = id;
return this;
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder email(String email) {
this.email = email;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
// 构建最终对象
public User build() {
return new User(id, name, age, email, address);
}
@Override
public String toString() {
return "User.UserBuilder(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", email=" + this.email + ", address=" + this.address + ")";
}
}
// 便捷的builder()方法
public static UserBuilder builder() {
return new UserBuilder();
}
}
四、使用方式
// 使用Builder创建对象
User user = User.builder()
.id(1L)
.name("张三")
.age(25)
.email("zhangsan@example.com")
.address("北京市朝阳区")
.build();
五、@Builder 的高级特性
- 指定构建顺序和必需参数
@Builder
@Data
public class Order {
// @Builder.Required 表示该参数是必需的
@Builder.Required
private Long orderId;
private String customerName;
private LocalDateTime orderTime;
// 指定构建顺序
@Builder.Default
private OrderStatus status = OrderStatus.CREATED;
}
- 处理复杂初始化逻辑
@Builder
@Data
public class Product {
private Long id;
private String name;
private BigDecimal price;
// 自定义构建逻辑
@Builder.Default
private Date createTime = new Date();
// 构建后处理
@Builder.ObtainVia(method = "calculateDiscountPrice")
private BigDecimal discountPrice;
private BigDecimal calculateDiscountPrice() {
return price.multiply(new BigDecimal("0.9")); // 九折优惠
}
}
- 与其他Lombok注解结合使用
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Long id;
private String title;
private String author;
private double price;
private int pageCount;
}
- 继承场景下的Builder
// 父类
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
abstract class Animal {
private String name;
private int age;
private String color;
}
// 子类
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
class Dog extends Animal {
private String breed;
private boolean isTrained;
}
六、@Builder 的注意事项
- 性能考虑:Builder模式会创建额外的对象(Builder类),在性能敏感场景需谨慎
- 不可变性:配合
@Immutable
可创建不可变对象 - 与构造函数的兼容性:Builder生成的是私有的构造函数,如需公共构造函数需额外声明
- 序列化问题:如果类需要序列化,Builder类也需要实现
Serializable
接口 - 复杂继承场景:多层继承时Builder的使用会变得复杂,需额外配置
七、@Builder 与其他创建对象方式的对比
创建方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
构造函数 | 简单直接 | 参数多时有歧义,可读性差 | 简单对象,参数少 |
工厂方法 | 灵活,可返回子类实例 | 增加类复杂度 | 需要多态创建对象 |
Builder模式 | 清晰的API,可处理复杂对象 | 代码量增加 | 复杂对象,多参数配置 |
八、最佳实践
- 用于参数较多(超过4个)的类
- 配合
@Data
一起使用,减少样板代码 - 对必需参数使用
@Builder.Required
- 对有默认值的参数使用
@Builder.Default
- 在复杂初始化逻辑中使用
@Builder.ObtainVia
- 考虑与
@Singular
结合处理集合类型参数
通过使用Lombok的@Builder
注解,我们可以在保持代码简洁的同时,享受建造者模式带来的灵活性和可读性,尤其在处理复杂对象的创建时优势更为明显。