2020年3月发布的JDK 14引入了记录 (预览语言功能),这些记录提供了一种紧凑的语法来声明主要用于保存数据的类。 在记录中 ,所有低级,重复且容易出错的代码都类似于构造函数,访问器和通用方法,例如equals()
, hashCode()
和toString()
都是根据记录的状态描述自动得出的。
先决条件
您将需要启用了预览功能的JDK 14。
了解如何使用SDKMAN管理多个Java SDK! 轻松
我们将
记录申报
记录具有名称和状态描述。 状态描述声明记录的组成部分 ,并可选地声明主体:
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://openjdk.java.net/jeps/359
翻译自: https://www.javacodegeeks.com/2020/05/record-type-in-java.html