是否有使用继承的方法来使用记录(Records)?

48

我有一堆使用 Lombok 的 @Data 类,现在想将它们全部迁移到 Java 14 中提供的新记录功能。

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

主要问题涉及继承。我有一个类 B 继承自类 A。有没有办法在记录中使用继承?

2个回答

55
JEP 表示:

关于记录的限制

记录不能扩展任何其他类,也不能声明除了对应于状态描述组件的私有 final 字段之外的任何实例字段。声明的任何其他字段必须是静态的。这些限制确保仅状态描述定义了表示。

Java 17 JLS 8.10 声明1

一个 record 声明不包含 extends 子句,因此不能显式地声明直接超类类型,即使是 Record 也一样。

然而,record 可以实现接口,因此可以使用多态。此外,由于记录将继承它们实现的接口中的任何默认方法,它们支持一种有限的继承形式。


1 - 这是一个非规范性语句,但由于指定的 RecordDeclaration 语法明确不允许使用 extends,所以显然是正确的。


6
继承一个拥有默认方法的接口听起来非常灵活/强大......我正准备尝试一下...... - davidbak
是的,它确实运行良好! - davidbak

39

如何在继承中使用记录(records)?

记录(records)已经扩展了 java.lang.Record。由于Java不允许多重继承,因此记录(records)不能扩展任何其他类。

例如,考虑以下记录(record)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();
}

1
如果记录Derived扩展自记录Base且Base扩展自java.lang.Record,那么Derived在传递上扩展了Record。没有必要进行多重继承,这只是糟糕的语言设计,希望在将来的某个时候得到解决。 - Serid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接