Java 14 記錄與龍目島
一、概述
Java 的記錄關鍵字是 Java 14 中引入的新語義特性。記錄對於創建小的不可變對象非常有用。另一方面, Lombok 是一個 Java 庫,可以自動生成一些已知模式作為 Java 字節碼。儘管它們都可以用來減少樣板代碼,但它們是不同的工具。因此,我們應該在給定的上下文中使用更適合我們需求的那個。
在本文中,我們將探討各種用例,包括 java 記錄的一些限制。對於每個示例,我們將了解 Lombok 如何派上用場並比較兩種解決方案。
2. 小的不可變對象
對於我們的第一個示例,我們將使用Color
對象。 Color
由三個整數值組成,分別代表紅色、綠色和藍色通道。此外,顏色將暴露其十六進製表示。例如, RGB(255,0,0)
的顏色將具有#FF0000
的十六進製表示。此外,如果兩種顏色具有相同的 RGB 值,我們希望它們equal
。
由於這些原因,在這種情況下選擇record
將非常有意義:
public record ColorRecord(int red, int green, int blue) {
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
同樣,Lombok 允許我們使用@Value
註釋創建不可變對象:
@Value
public class ColorValueObject {
int red;
int green;
int blue;
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
然而,從 Java 14 開始, records
將成為這些用例的自然方式。
3. 透明的數據載體
根據 JDK 增強提案 ( JEP 395 ),記錄是充當不可變數據的透明載體的類。因此,我們無法阻止記錄公開其成員字段。例如,我們不能強制前面示例中的ColorRecord
隻公開hexString
並完全隱藏三個整數字段。
但是,Lombok 允許我們自定義 getter 的名稱、訪問級別和返回類型。讓我們相應地更新ColorValueObject
:
@Value
@Getter(AccessLevel.NONE)
public class ColorValueObject {
int red;
int green;
int blue;
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
因此,如果我們需要不可變的數據對象,記錄是一個很好的解決方案。
但是,如果我們想隱藏成員字段並隻公開使用它們執行的一些操作,Lombok 將更適合。
4. 多領域的類
我們已經看到記錄是如何代表一種非常方便的方式來創建小的、不可變的對象的。讓我們看看如果數據模型需要更多字段,記錄會是什麼樣子。對於此示例,讓我們考慮Student
數據模型:
public record StudentRecord(
String firstName,
String lastName,
Long studentId,
String email,
String phoneNumber,
String address,
String country,
int age) {
}
我們已經可以猜到 StudentRecord 的實例化將難以閱讀和理解,特別是如果某些字段不是強制性的:
StudentRecord john = new StudentRecord(
"John", "Doe", null, "[email protected]", null, null, "England", 20);
為了方便這些用例,Lombok 提供了 Builder 設計模式的實現。
為了使用它,我們只需要用@Builder:
@Getter
@Builder
public class StudentBuilder {
private String firstName;
private String lastName;
private Long studentId;
private String email;
private String phoneNumber;
private String address;
private String country;
private int age;
}
現在,讓我們使用StudentBuilder
創建一個具有相同屬性的對象:
StudentBuilder john = StudentBuilder.builder()
.firstName("John")
.lastName("Doe")
.email("[email protected]")
.country("England")
.age(20)
.build();
如果我們比較兩者,我們會注意到使用構建器模式是有利的,從而導致代碼更簡潔。
總之,記錄更適合較小的對象。但是,對於具有許多字段的對象,缺少創建模式將使 Lombok 的@Builder
成為更好的選擇。
5. 可變數據
我們可以將 java 記錄專門用於不可變數據。如果上下文需要一個可變的 java 對象,我們可以使用 Lombok 的@Data
對象來代替:
@Data
@AllArgsConstructor
public class ColorData {
private int red;
private int green;
private int blue;
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
一些框架可能需要帶有 setter 或默認構造函數的對象。例如,Hibernate 就屬於這一類。創建@Entity,
我們必須使用 Lombok 的註解或純 Java。
6. 繼承
Java 記錄不支持繼承。因此,它們不能擴展或繼承其他類。另一方面,Lombok 的@Value
對象可以擴展其他類,但它們是最終的:
@Value
public class MonochromeColor extends ColorData {
public MonochromeColor(int grayScale) {
super(grayScale, grayScale, grayScale);
}
}
此外, @Data
對象既可以擴展其他類,也可以擴展。總之,如果我們需要繼承,我們應該堅持Lombok的解決方案。
7. 結論
在本文中,我們看到 Lombok 和 java 記錄是不同的工具,服務於不同的目的。此外,我們發現 Lombok 更靈活,可以用於記錄有限的場景。
與往常一樣,源代碼可在 GitHub 上獲得。