2020年3月发布的JDK 14引入了记录 (预览语言功能),这些记录提供了一种紧凑的语法来声明主要用于保存数据的类。 在记录中 ,所有低级,重复且容易出错的代码都类似于构造函数,访问器和通用方法,例如equals()
, hashCode()
, toString()
都是根据记录的状态描述自动得出的。
先决条件
您将需要启用了预览功能的JDK 14。
我们将
记录申报
记录具有名称和状态描述。 状态描述声明记录的组成部分 ,并可选地声明主体:
record Owner(String name, String address, String city, String telephone) {} record PetType(String name) {} record Pet(LocalDate birthDate, PetType type, Owner owner) {}
记录的表示是通过以下成员从状态描述中机械而完全地得出的:
- 每个组件的
private
final
字段 - 每个组件的
public
读取访问器方法,其名称和类型与该组件相同(例如owner.name()
,owner.address()
) -
public
建设者 -
equals()
和hashCode()
-
toString()
的实现。
下面的测试演示了基本行为:
class Java14RecordTests {
@Test
void recordAccessors() {
var owner = new Owner( "John Doe" , "110 W. Liberty St." , "Madison" , "6085551023" );
assertThat(owner.name()).isEqualTo( "John Doe" );
assertThat(owner.address()).isEqualTo( "110 W. Liberty St." );
assertThat(owner.city()).isEqualTo( "Madison" );
assertThat(owner.telephone()).isEqualTo( "6085551023" );
}
@Test
void recordEqualsAndHashCode() {
var pet1 = new Pet(
LocalDate.of( 2019 , 1 , 1 ),
new PetType( "dog" ),
new Owner( "John Doe" , null , null , null )
);
var pet2 = new Pet(
LocalDate.of( 2019 , 1 , 1 ),
new PetType( "dog" ),
new Owner( "John Doe" , null , null , null )
);
assertThat(pet1).isEqualTo(pet2);
assertThat(pet1.hashCode()).isEqualTo(pet2.hashCode());
}
@Test
void recordToString() {
var pet = new PetType( "dog" );
assertThat(pet.toString()).isEqualTo( "PetType[name=dog]" );
} }
限制条件
记录是类的一种受限形式,其限制是:
- 记录不能扩展任何其他类别
- 声明的任何其他字段必须为静态
- 记录的组成部分是隐式最终的
额外行为
除上述限制外, 记录的行为类似于常规类,并且:
- 记录可以声明实例和静态方法,静态字段,静态初始化程序:
record Owner(String name, String address, String city, String telephone) {
/* Static initializer */
static {
NONE = "N/A" ;
}
/* Static fields are allowed, both private and public */
private static String NONE;
/* Records may have static methods */
public static Owner anOwner(String name) {
return new Owner(name, NONE, NONE, NONE);
} }
- 记录可以声明构造函数,也可以声明紧凑构造函数。 紧凑的构造函数可以访问记录的组件:
record Pet(LocalDate birthDate, PetType type, Owner owner) {
/* `Compact` constructor */
public Pet {
"birthDate" requiresNotNull( "birthDate" , birthDate);
requiresNotNull( "type" , type);
requiresNotNull( "owner" , owner);
}
public Pet(LocalDate birthDate, PetType type) {
this (birthDate, type, null );
}
/* Records may have instance methods */
private void requiresNotNull(String name, Object obj) {
if (Objects.isNull(obj)) {
throw new IllegalArgumentException(name + " can't be null" );
}
} }
- 记录可以覆盖所有标准方法:
equals()
,hashCode()
,toString()
- 记录可以实现接口
- 记录可以注释
… 和更多。
源代码
可以在Github上找到本文的源代码: https : //github.com/kolorobot/java9-and-beyond
参考文献
翻译自: https://www.javacodegeeks.com/2020/05/record-type-in-java.html