我有一堆使用 Lombok 的
@Data
类,我想迁移所有这些类以使用 Java 14 中提供的新记录功能。
我知道现在有点早了,但这是我正在进行的实验测试。
这里的主要问题涉及继承。我有一个类 B,它扩展了类 A。有没有办法通过继承来使用 Records?
JEP 指出:
记录限制
记录不能扩展任何其他类,并且不能声明除与状态描述的组件相对应的私有最终字段之外的实例字段。声明的任何其他字段都必须是静态的。这些限制确保状态描述单独定义表示。
Java 17 JLS 8.10 注释1:
声明没有record
子句,因此不可能显式声明直接超类类型,即使是extends
。Record
但是,有
record
can implement
接口,因此您可以多态地使用它们。 此外,由于记录将继承它们实现的接口中的任何 default
方法,因此它们确实支持有限形式的继承。
1 - 这是一个非规范的声明,但它显然是正确的,因为 RecordDeclaration 的指定语法显然不允许使用
extends
。
有什么方法可以使用带有继承的记录吗?
java.lang.Record
。由于 Java 不允许多重继承,因此记录不能扩展任何其他类。
例如,考虑以下记录
Point
:
public record Point(double x, double y) {}
您可以使用以下方式编译它:
javac --enable-preview -source 14 Point.java
javap
的帮助下,您可以了解有关Point
生成的代码的详细信息:
javap -p Point
输出将是:
Compiled from "Point.java"
public final class Point extends java.lang.Record {
private final double x;
private final double y;
public Point(double, double);
public java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public double x();
public double y();
}
正如@StephenC之前提到的
由于记录将继承它们实现的接口中的任何默认方法,因此它们确实支持有限形式的继承。
假设您有一个参数化测试 有测试数据方法来源
static Stream<TestData> tDS() {return Stream.of(...);}
使用记录实现
TestData
的一种方法可能是
public record InputData(int cellIndex){}
public record ExpectedResult (int rowY, int colX) {}
public record TestData<I, E>(I input, E expected) {}
另一个带有接口的选项可能是
public sealed interface InputData<I> permits CellIndexInput {
I getInputData();}
public sealed interface ExpectedResult<E> permits ExpectedRowColumn {
E getExpectedResult();}
public record CellIndexInput(int cellIndex) implements InputData {
@Override
public CellIndexInput getInputData(){return this;}}
public record ExpectedRowColumn(int rowY, int colX) implements ExpectedResult {
@Override
public ExpectedRowColumn getExpectedResult(){return this;}}
public record TestData(InputData input, ExpectedResult expected) {}
请注意:在这两种情况下都可以访问实际数据
模式匹配可能会有所帮助,
例如:与
switch
与 default -> ...
(用于详尽匹配)if (testData.input() instanceof CellIndexInput(int cellIndex) &&
testData.expected() instanceof ExpectedRowColumn(int rowY, int colX)
) {...
assertEquals(rowY, ...); ...
} else {fail("of TestData pattern matching");}