JEP 359 (可在JDK 14中用作预览功能)将记录引入Java。 记录是对普通数据聚合建模的简单方法。
一个简单的范围记录如下所示:
record Range( int from, int to) {}
记录定义实际上与具有以下内容的最终类相同:
- 不变的领域
- 公共访问者
- 构造函数
- equals(),hashCode()和toString()的实现
因此我们可以像这样使用记录:
Range range = new Range( 1 , 5 ); int from = range.from(); // 1 int to = range.to(); // 5 String toString = range.toString(); // Range[from=1, to=5] boolean equals = range.equals( new Range( 1 , 5 )); // true
请注意,访问器的名称是from()和to(),而不是getFrom()和getTo()。
构造函数呢?
假设我们要向Record中添加一个构造函数以执行一些验证:
record Range( int from, int to) { public Range( int from, int to) { if (from > to) { throw new IllegalArgumentException(); } this .from = from; this .to = to; } }
这样可以避免创建无效的Range实例。 但是,我们不得不多次写下from和to字段来执行简单的验证,这有点令人讨厌。
为了避免这种情况,我们可以使用一种特殊形式的记录构造函数,称为紧凑构造函数。 这使我们可以跳过定义构造函数参数并将构造函数参数分配给字段的操作。 看起来像这样:
record Range( int from, int to) { public Range { if (from > to) { throw new IllegalArgumentException(); } } }
结果与之前的构造函数完全相同。
定制方法
我们还可以添加新方法并覆盖记录中的现有方法。
例如:
record Range( int from, int to) { public int getDistance() { return to - from; } @Override public String toString() { return String.format( "Range[from: %s, to: %s, distance: %s]" , from, to, getDistance()); } }
为什么记录有用?
如果我们需要一个简单的类来传递数据,记录只会减少我们必须编写的代码量。 用例示例是方法,复合映射键或数据传输对象的多个返回值。
假设您要在集合中找到最小值和最大值。 通过一条记录,您可以只用一行创建两个值的返回类型:
record MinMax( int min, int max) {} static MinMax minMax(Collection<Integer> numbers) { ... }
(是的,您可以使用单独的方法来找到最小值和最大值。但是,然后您必须对集合进行两次迭代)
记录还提供了一种创建复合Map键的简便方法:
record NameAndDayOfBirth(String name, LocalDate dob) {} private Map<NameAndDayOfBirth, Person> entries = ...;
摘要
记录提供了一种不太冗长的方式来创建简单的数据持有人。 常见的用例是多个返回值,复合映射键或数据传输对象。 有关记录的更多背景信息,我推荐Brian Goetz撰写的这篇文章 。
您可以在GitHub上找到示例代码。
翻译自: https://www.javacodegeeks.com/2020/05/looking-at-java-records.html