JEP Link: https://openjdk.org/jeps/395
1. 基本用法介绍
Java record 关键字是 Java 14 中引入的一个新的语义特性,对于创建小型不可变对象非常有用。
// record in Java 17
public record PointRecord(int x, int y) {
public int getRange() {
return Math.abs(y - x);
}
}
在以上 Record 类中,定义了 x y 的 int 变量属性,并且定义了它的成员方法 getRange(),以上代码相当于:
import java.util.Objects;
class PointClass {
private final int x;
private final int y;
PointClass(int x, int y) {
this.x = x;
this.y = y;
}
int x() {
return x;
}
int y() {
return y;
}
public boolean equals(Object o) {
if (!(o instanceof PointClass other)) return false;
return other.x == x && other.y == y;
}
public int hashCode() {
return Objects.hash(x, y);
}
public String toString() {
return String.format("Point[x=%d, y=%d]", x, y);
}
public int getRange() {
return Math.abs(y - x);
}
}
用 record 关键字修饰的类相当于:
-
private final field(s) and coordinated public accessor method(s);
提供以 private final 修饰的成员变量和对应的公共访问 get 方法; -
a canonical constructor;
全参的构造方法; -
equals, hashCode, toString methods;
提供 equals, hashCode, toString 方法
2. 与 Lombok @Value 使用场景对比
reference: https://www.baeldung.com/java-record-vs-lombok
Lombok 是一个 Java 库,可以将一些已知的模板代码自动生成为Java字节码,尽管它们都可以用来减少样板代码,但它们是不同的工具。因此,我们应该在给定的上下文中分析使用更适合我们需要的那个:
-
共同点 - 常规用法,两种皆可
record & Lombok @Value
public record ColorRecord(int red, int green, int blue) {
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
@Value
public class ColorValueObject {
int red;
int green;
int blue;
public String getHexString() {
return String.format("#%02X%02X%02X", red, green, blue);
}
}
-
数据载体
JEP 395: record 是作为不可变数据的载体的类,因此,record 会强制公开所有的成员字段。但是,Lombok @Value 允许我们自定义 getter 的名称、访问级别和返回类型,这点来看 @Value 使用体验更佳:
@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);
}
}
- 包含很多属性的类
public record StudentRecord(
String firstName,
String lastName,
Long studentId,
String email,
String phoneNumber,
String address,
String country,
int age) {
}
由于 record 关键字默认提供全参构造,所以当有些字段属性并不是必须时,初始化 record 类会在一定程度上影响代码可读性:
StudentRecord stu = new StudentRecord("John", "Doe", null, "john@doe.com", null, null, "England", 20);
而 Lombok 使用 @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 stu = StudentBuilder.builder()
.firstName("John")
.lastName("Doe")
.email("john@doe.com")
.country("England")
.age(20)
.build();
综上,对于具有许多字段的对象,record 设计得并不是特别灵活,那么 Lombok @Builder确实是更好的选择。
-
可变数据
Java record 专门用于不可变数据,如果上下文需要一个可变的 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);
}
}
- 继承
Java record 不支持继承。因此,它们不能被扩展或继承其他类。而 Lombok @Value 修饰的对象可以继承 final 类,此外,@Data 修饰的对象既可以扩展其他类,也可以被扩展。总之,如果类需要继承,应该使用 Lombok @Value:
@Value
public class MonochromeColor extends ColorData {
public MonochromeColor(int grayScale) {
super(grayScale, grayScale, grayscale);
}
}
总结:Lombok 与 Java record 是不同的工具,服务于不同的目的。此外,Lombok 更加灵活,它可以用于 record 受限的场景。
以上,感谢浏览,如有不足请指正 😉

本文介绍了Java 17中的record关键字,它简化了创建不可变对象的过程,与Lombok的@Value进行了对比。记录了两者的基本用法、应用场景及优缺点。在大量字段的情况下,Lombok的@Builder提供了更多灵活性;而record不支持继承,适合不可变数据。总结来说,Lombok更为灵活,可适用于record无法覆盖的场景。

1355

被折叠的 条评论
为什么被折叠?



