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 @Setter @NoArgsConstructor @AllArgsConstructor @ToString @EqualsAndHashCode 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) { User user = User.builder() .username("john_doe") .email("john.doe@example.com") .build();
System.out.println(user); } }
|
@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; }
User user = User.builder() .username("john_doe") .email("john.doe@example.com") .build();
|
@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) .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) 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) { AdminUser admin = AdminUser.builder() .username("admin_user") .email("admin@example.com") .role("SUPER_ADMIN") .build();
System.out.println(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)
可以指定構造方法的訪問權限
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;
}
|
生成的代碼:
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; }
|
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;
@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; }
|
@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; }
|