1. 概述
Java 14 引入了新的语义特性——记录(Records),它们非常适合创建小型不可变对象。另一方面,** lombok 是一个可以自动生成已知模式的 Java 库**,通过将代码转换为字节码来简化工作。尽管两者都能减少样板代码,但它们是不同的工具。因此,在特定上下文中,我们应该选择更适合的工具。
本文将探讨各种用例,包括 Java 记录的一些限制,并在每个示例中展示如何使用 lombok,以及与这两种解决方案的比较。
2. 小型不可变对象
以 Color 对象为例。一个 Color 由三个整数值组成,代表红、绿、蓝通道。此外,颜色还提供其十六进制表示,如 RGB(255,0,0) 的十六进制表示为 #FF0000。而且,我们希望具有相同 RGB 值的两种颜色被认为是相等的。
在这种情况下,选择使用 记录 是非常合适的:
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 开始,对于这些场景,记录将是自然的选择。
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();
比较两者,我们可以看出使用 Builder 模式更可取,代码更清晰。
总的来说,记录更适合较小的对象。但对于包含许多字段的对象,缺少构造模式使得 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 上找到。