1 概述
Java Record
是一种不变类,类似于 String,Integer。让我们看一个简单的例子。
public record Data( int x, int y)
我们使用 record 关键字来创建记录类,它的等价类写法如下:
public final class Data {
final private int x;
final private int y;
public Data( int x, int y){
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
...
}
public int hashCode() {
...
}
public String toString() {
...
}
}
2 记录类的初始化
当我们声明一个没有任何构造函数的普通类时,编译器会提供一个没有参数的缺省构造函数。对于记类录,也会隐式创建构造函数。
public record Data(int x, int y) {
public Data {
if (x >y) {
throw new IllegalArgumentException();
}
x+=100;
y+=100;
}
}
在上面的记录类中,已经执行了一个简单的验证,验证后每个记录值增加100。等价的写法:
public final class Data {
final private int x;
final private int y;
public Data( int x, int y){
if (x >y) {
throw new IllegalArgumentException();
}
x+=100;
y+=100;
this.x = x;
this.y = y;
}
}
3 记录类不能继承,也不支持继承
记录类不支持继承,不能用任何其他类来继承它,也不能用记录类来继承它。它唯一的父类是 java.lang.Record
。
4 可以实现接口
记录类可以实现接口,无论它是单个接口还是多个接口。
public record Data( int x, int y) implements Runnable, Serializable
5 无法定义自己的实例变量
定义记录类时,只有头部组件中提供的实例变量才会被创建。
但是,可以在记录中包含静态变量,通过使用记录类名,可以像访问类一样访问这些静态变量。
6 定义方法
可以在记录类里定义方法,包括accessor、equals、hashcode
方法。然而,您需要确保不会打破记录类的不可变性。
7 局部记录类
当我们只想在函数中临时保存不可变数据时,记录类会非常好用。
public List<Person> sortPeopleByAge(List<Person> people) {
record Data(Person person, int age){};
return people.stream()
.map(person -> new Data(person, computeAge(person)))
.sorted((d1, d2) -> Double.compare(d2.age(), d1.age()))
.map(Data::person)
.collect(toList());
}
例子创建了一个局部记录类,它能让代码变得简洁易懂。