lombok

lombok

Lombok 是一個 Java 庫,用於減少樣板代碼(boilerplate code)的生成,通過簡單的註解來自動生成常見的代碼,例如 getter、setter、equals()、hashCode()、toString()、構造方法等。

依賴

Maven

1
2
3
4
5
6
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 請根據需要選擇最新版本 -->
<scope>provided</scope>
</dependency>

Gradle

1
2
implementation 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
import lombok.*;

@Getter // 自動生成 Getter 方法
@Setter // 自動生成 Setter 方法
@NoArgsConstructor // 無參構造方法
@AllArgsConstructor // 包含所有屬性的構造方法
@ToString // 自動生成 toString 方法
@EqualsAndHashCode // 自動生成 equals 和 hashCode 方法
public class User {
private Long id;
private String username;
private String email;
}

@Builder

適用於單一類別,無法處理繼承層級中的屬性。

1
2
3
4
5
6
7
8
9
import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class User {
private String username;
private String email;
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
// 使用 Builder 創建 User 對象
User user = User.builder()
.username("john_doe")
.email("john.doe@example.com")
.build();

System.out.println(user);
// 輸出: User(username=john_doe, email=john.doe@example.com)
}
}

@Builder.Default

當與 @Builder 一起使用時,這個註解使你能夠為屬性指定默認值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Builder
public class User {
private String username;
private String email;
@Builder.Default
private int age = 30; // 默認值為30
}

User user = User.builder()
.username("john_doe")
.email("john.doe@example.com")
.build();
// age 默認為 30

@Builder(toBuilder = true)

生成一個 toBuilder() 方法,允許你基於已有對象來創建一個新的建造者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Builder(toBuilder = true)
public class User {
private String username;
private String email;
private int age;
}

User user = User.builder()
.username("john_doe")
.email("john.doe@example.com")
.age(25)
.build();

User updatedUser = user.toBuilder()
.age(30) // 修改 age
.build();

@SuperBuilder

支持繼承,允許在子類中同時初始化父類與子類的屬性。

父類(User)

1
2
3
4
5
6
7
8
9
10
11
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
@ToString
public class User {
private String username;
private String email;
}

子類(AdminUser)

1
2
3
4
5
6
7
8
9
10
11
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
@ToString(callSuper = true) // 繼承父類的 toString 方法
public class AdminUser extends User {
private String role;
}

使用 @SuperBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args) {
// 使用 SuperBuilder 創建 AdminUser 對象
AdminUser admin = AdminUser.builder()
.username("admin_user")
.email("admin@example.com")
.role("SUPER_ADMIN")
.build();

System.out.println(admin);
// 輸出: AdminUser(super=User(username=admin_user, email=admin@example.com), role=SUPER_ADMIN)
}
}

區別

特性 @Builder @SuperBuilder
適用範圍 僅適用於單一類別 支持繼承層級,適用於父類與子類的屬性共同初始化
父類屬性支持 無法處理繼承,僅生成當前類別的屬性 支持子類初始化時同時設置父類的屬性
配置靈活性 更簡單,適合沒有繼承關係的類 更強大,適合存在繼承結構的類
使用註解位置 @Builder 註解在類上即可 @SuperBuilder 註解在類上,且需要父類也使用 @SuperBuilder

@NoArgsConstructor 無參構造方法

1
2
3
4
5
6
7
8
import lombok.NoArgsConstructor;

@NoArgsConstructor
public class User {
private String username;
private String email;
private int age;
}

生成的代碼:

1
2
3
4
5
6
7
8
9
public class User {
private String username;
private String email;
private int age;

public User() {
// 無參構造方法
}
}

@AllArgsConstructor

功能:

會生成一個包含所有屬性的構造方法。這對於需要初始化所有字段的場景非常有用。

@AllArgsConstructor(access = AccessLevel.PROTECTED)

可以指定構造方法的訪問權限

  • private
  • protected
  • public
1
2
3
4
5
6
7
8
9
10
import lombok.AllArgsConstructor;

@AllArgsConstructor
public class User {
private String username;
private String email;
private int age;

// 這裡會生成一個構造方法:User(String username, String email, int age)
}

生成的代碼:

1
2
3
4
5
6
7
8
9
10
11
public class User {
private String username;
private String email;
private int age;

public User(String username, String email, int age) {
this.username = username;
this.email = email;
this.age = age;
}
}

@ToString

@ToString 會自動生成 toString() 方法,該方法返回類的屬性值

參數

  • **@ToString(includeFieldNames = false)**:是否顯示屬性名稱,默認為 true。
  • **@ToString(callSuper = true)**:是否調用父類的 toString() 方法。
  • **@ToString(exclude = {“password”, “email”})**:排除某些屬性不顯示在 toString() 的結果中。
1
2
3
4
5
6
7
8
9
public class BaseEntity {
private Long id;

@Override
public String toString() {
return "BaseEntity(id=" + id + ")";
}
}

1
2
3
4
5
6
7
8
@ToString(callSuper = true, exclude = {"password"})
public class User extends BaseEntity {
private String username;
private String email;
private String password;

// 這裡會生成 toString() 方法,並排除 `password` 屬性
}
1
2
3
4
5
6
7
8
9
10
11
public class User extends BaseEntity {
private String username;
private String email;
private String password;

// 這裡會生成 toString() 方法,並排除 `password` 屬性
@Override
public String toString() {
return "User(super=" + super.toString() + ", username=" + username + ", email=" + email + ")";
}
}

最終輸出

1
User(super=BaseEntity(id=1), username=john_doe, email=john.doe@example.com)

@EqualsAndHashCode

用於自動生成 equals() 和 hashCode() 方法

1
2
3
4
5
6
7
8
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true, exclude = {"password"})
public class User extends BaseEntity {
private String username;
private String email;
private String password;
}

實際產生代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BaseEntity {
private Long id;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BaseEntity that = (BaseEntity) o;
return Objects.equals(id, that.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Objects;

public class User extends BaseEntity {
private String username;
private String email;
private String password;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
User user = (User) o;
return Objects.equals(username, user.username) &&
Objects.equals(email, user.email);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), username, email);
}
}

callSuper

默認為 false。設置為 true 時,equals() 和 hashCode() 方法會調用父類的 equals() 和 hashCode() 方法。

1
2
3
4
5
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {
private String username;
private String email;
}

exclude

用來排除某些屬性,這些屬性將不會被納入 equals() 和 hashCode() 的比較範圍。

1
2
3
4
5
6
@EqualsAndHashCode(exclude = {"password"})
public class User {
private String username;
private String email;
private String password;
}

onlyExplicitlyIncluded

默認為 false。設置為 true 時,只有被顯式標註為 @EqualsAndHashCode.Include 的屬性才會被用於 equals() 和 hashCode() 的生成。

1
2
3
4
5
6
7
8
9
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
@EqualsAndHashCode.Include
private String username;
@EqualsAndHashCode.Include
private String email;
private String password; // 不會被包含在 equals 和 hashCode 中
}

@EqualsAndHashCode.Include

用於指定特定屬性應參與 equals() 和 hashCode() 的比較。如果 onlyExplicitlyIncluded 設置為 true,則只有這些屬性會參與比較。

1
2
3
4
5
6
7
8
public class User {
@EqualsAndHashCode.Include
private String username;
@EqualsAndHashCode.Include
private String email;
private String password; // 不會參與比較
}


lombok
https://shengshengyang.github.io/2024/12/18/lombok/
作者
Dean Yang
發布於
2024年12月18日
許可協議