在 Java 中,record
类型是一种特殊的类,它在 Java 14 中作为预览功能引入,并在 Java 16 中正式成为语言的一部分。record
类型提供了一种简洁且高效的方式来创建不可变的数据载体类。
Record 类型的特点
-
简洁的语法:
record
类型减少了创建不可变类所需的样板代码。它自动为所有字段生成构造函数、toString()
、equals()
和hashCode()
方法,极大地简化了代码的编写。public record Person(String name, int age) { }
上面的
record
定义了一个包含name
和age
两个字段的不可变数据类型。编译器会自动为这些字段生成构造函数、getName()
和getAge()
方法。 -
不可变性:
record
类型的字段默认是final
的,因此一旦对象被创建,其状态不可更改。这个不可变的特性对于创建数据载体类(比如值对象)非常重要,能提供线程安全性和减少副作用。 -
自动生成方法:
Java 编译器会自动为record
生成以下方法:- 构造函数:接收所有字段的参数,并初始化它们。
accessor
方法:每个字段都有一个公共的方法用于获取其值,方法名与字段名一致(例如name()
和age()
)。equals()
:基于所有字段的值生成的equals()
方法。hashCode()
:基于所有字段的值生成的hashCode()
方法。toString()
:生成一个包含所有字段名称和值的字符串表示。
-
数据封装:
record
类型提供了一种天然的数据封装方式,它将数据字段的定义和行为捆绑在一起,使得对象的状态与行为一目了然。 -
继承限制:
record
类型不能被继承。它隐式地继承了java.lang.Record
类,并且不能有其他子类。record
类型也不能继承其他类,只能实现接口。 -
自定义行为:
尽管record
类型生成了默认的构造函数、equals()
、hashCode()
和toString()
方法,但你可以自定义这些方法。如果需要额外的逻辑,可以在record
中添加方法,但字段的不可变性仍然保留。public record Person(String name, int age) { public Person { if (age < 0) { throw new IllegalArgumentException("Age cannot be negative"); } } @Override public String toString() { return "Person[name=" + name + ", age=" + age + "]"; } }
使用示例
下面是一个 record
类型的简单示例:
public record Point(int x, int y) { }
public class Main {
public static void main(String[] args) {
Point p = new Point(1, 2);
System.out.println(p.x()); // 输出 1
System.out.println(p.y()); // 输出 2
System.out.println(p); // 输出 Point[x=1, y=2]
}
}
在这个示例中,我们定义了一个 Point
类型的 record
,它有两个字段 x
和 y
。创建 Point
实例后,可以看到自动生成的方法如 x()
和 y()
,以及重写的 toString()
方法。
record
类型是 Java 中一种重要的特性,它使得数据载体类的创建变得更加简洁和高效,同时保持了 Java 语言的一贯风格和特性。