使用Record建模不可变数据
Java语言提供了多种创建不可变类的方法。最直接的方式可能是创建一个包含final字段和构造函数的final类,用于初始化这些字段。以下是一个此类类的示例。
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
既然你已经编写了这些元素,接下来需要为字段添加访问器方法。你还需要添加 toString() 方法,可能还需要 equals() 方法以及 hashCode() 方法。手动编写所有这些方法相当繁琐且容易出错,所幸你的集成开发环境(IDE)可以为你自动生成这些方法。
若需将该类的实例从一个应用程序传递至另一个应用程序(无论是通过网络传输还是文件系统传输),您也可考虑使该类具备序列化能力。若选择此方案,您可能需要添加关于该类实例序列化方式的相关信息。JDK提供了多种控制序列化的方法。
最终,你的 Point 类可能长达上百行,其中大部分是IDE生成的代码,仅仅是为了建模一个需要写入文件的两个整数的不可变聚合。
为改变这种状况,JDK引入了Record类型。Record类型只需一行代码就能实现这一切。你只需声明记录的状态,其余部分由编译器自动生成。
使用Record来建模
Record的存在正是为了帮助你简化这段代码。从Java SE 14开始,你可以编写以下代码:
public record Point(int x, int y) {}
这行代码为您创建了以下元素。
- 这是一个不可变类,包含两个字段:x 和 y,类型均为 int。
- 它具有一个标准构造函数,用于初始化这两个字段。
- 编译器已为您创建了 toString()、equals() 和 hashCode() 方法,其默认行为与IDE生成的行为一致。如有需要,您可以通过添加这些方法的自定义实现来修改其行为。
- 它可以实现 Serializable 接口,从而能够通过网络或文件系统将Point实例发送至其他应用程序。记录的序列化和反序列化过程遵循特定规则,这些规则将在本教程末尾进行说明。
Record 使创建不可变数据集合变得更加简单,无需任何IDE的辅助。它降低了出现错误的风险,因为每次修改记录的组件时,编译器都会自动为您更新 equals() 和 hashCode() 方法。