@Builder
是 Lombok 库中的一个注解,用于为类生成一个 Builder 模式的实现。Builder 模式是一种创建型设计模式,旨在通过使用链式调用来简化复杂对象的创建过程。使用 @Builder
注解可以显著减少样板代码,使类的构造更加简洁和易读。
基本用法
假设有一个包含多个字段的类:
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class User {
private String name;
private int age;
private String email;
}
通过 @Builder
注解,Lombok 会自动为 User
类生成一个内部静态 Builder 类,并提供相应的构建方法。
生成的代码
Lombok 会为 User
类生成如下代码:
public class User {
private String name;
private int age;
private String email;
User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
private String name;
private int age;
private String email;
UserBuilder() {
}
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 User build() {
return new User(name, age, email);
}
public String toString() {
return "User.UserBuilder(name=" + this.name + ", age=" + this.age + ", email=" + this.email + ")";
}
}
// Getter methods
}
使用示例
通过生成的 Builder 类,可以以链式调用的方式创建 User
对象:
public class Main {
public static void main(String[] args) {
User user = User.builder()
.name("John Doe")
.age(30)
.email("john.doe@example.com")
.build();
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());
System.out.println("Email: " + user.getEmail());
}
}
注意事项
-
字段默认值:
@Builder
注解不会处理字段的默认值。如果需要为字段设置默认值,可以在类的构造函数中进行处理。
-
不可变对象:
@Builder
注解可以与@Value
注解结合使用,生成不可变对象。@Value
注解会使类和字段变为 final,并生成相应的 getter 方法。
-
部分构建:
- Builder 模式允许部分构建对象,即不必为所有字段提供值。这在某些场景下非常有用,例如在构建复杂对象时逐步设置属性。
-
自定义构造函数:
- 如果类已经有一个或多个构造函数,
@Builder
注解会生成一个包含所有字段的构造函数,并使用该构造函数来创建对象。
- 如果类已经有一个或多个构造函数,
下面通过具体的代码示例来说明上述几点:
字段默认值
假设我们希望 User
类的某些字段有默认值,可以在类的构造函数中进行处理:
import lombok.Builder;
import lombok.Getter;
import lombok.AllArgsConstructor;
@Builder
@Getter
@AllArgsConstructor
public class User {
private String name;
private int age;
private String email;
// 自定义构造函数,设置默认值
public User(String name, int age) {
this(name, age, "default@example.com");
}
}
使用示例:
public class Main {
public static void main(String[] args) {
User user = User.builder()
.name("John Doe")
.age(30)
.build();
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());
System.out.println("Email: " + user.getEmail()); // 输出: default@example.com
}
}
不可变对象
结合 @Value
注解生成不可变对象:
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class ImmutableUser {
private String name;
private int age;
private String email;
}
使用示例:
public class Main {
public static void main(String[] args) {
ImmutableUser user = ImmutableUser.builder()
.name("John Doe")
.age(30)
.email("john.doe@example.com")
.build();
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());
System.out.println("Email: " + user.getEmail());
}
}
部分构建
Builder 模式允许部分构建对象,即不必为所有字段提供值:
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class PartialUser {
private String name;
private int age;
private String email;
}
使用示例:
public class Main {
public static void main(String[] args) {
PartialUser user = PartialUser.builder()
.name("John Doe")
.age(30)
.build();
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());
System.out.println("Email: " + user.getEmail()); // 输出: null
}
}
自定义构造函数
如果类已经有一个或多个构造函数,@Builder
注解会生成一个包含所有字段的构造函数,并使用该构造函数来创建对象:
import lombok.Builder;
import lombok.Getter;
import lombok.AllArgsConstructor;
@Builder
@Getter
@AllArgsConstructor
public class CustomUser {
private String name;
private int age;
private String email;
// 自定义构造函数
public CustomUser(String name, int age) {
this(name, age, "default@example.com");
}
}
使用示例:
public class Main {
public static void main(String[] args) {
CustomUser user = CustomUser.builder()
.name("John Doe")
.age(30)
.build();
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());
System.out.println("Email: " + user.getEmail()); // 输出: default@example.com
}
}
通过这些示例,可以看到 @Builder
注解如何与字段默认值、不可变对象、部分构建和自定义构造函数结合使用,从而简化对象的创建过程。