有什么方法可以通过继承来使用Records吗?

问题描述 投票:0回答:3

我有一堆使用 Lombok 的

@Data
类,我想迁移所有这些类以使用 Java 14 中提供的新记录功能。

我知道现在有点早了,但这是我正在进行的实验测试。

这里的主要问题涉及继承。我有一个类 B,它扩展了类 A。有没有办法通过继承来使用 Records?

java record java-record
3个回答
82
投票

JEP 指出:

记录限制

记录不能扩展任何其他类,并且不能声明除与状态描述的组件相对应的私有最终字段之外的实例字段。声明的任何其他字段都必须是静态的。这些限制确保状态描述单独定义表示。

Java 17 JLS 8.10 注释1

record
声明没有
extends
子句,因此不可能显式声明直接超类类型,即使是
Record

但是,有

record
can
implement
接口,因此您可以多态地使用它们。 此外,由于记录将继承它们实现的接口中的任何
default
方法,因此它们确实支持有限形式的继承。


1 - 这是一个非规范的声明,但它显然是正确的,因为 RecordDeclaration 的指定语法显然不允许使用

extends


43
投票

有什么方法可以使用带有继承的记录吗?

记录已经延长了

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();
}

0
投票

正如@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");}
© www.soinside.com 2019 - 2024. All rights reserved.