记录是类的句法糖吗?

Are records syntactic sugar for classes?

提问人:guizo792 提问时间:11/16/2023 最后编辑:Basil Bourqueguizo792 更新时间:11/17/2023 访问量:1800

问:

我最近发现了 Java 记录,了解它们的存在和用途真是太棒了。

然而,我开始怀疑它们本质上是否只是幕后的课程。

这是否意味着在编译过程中,它们被转换为具有最终私有字段、公共构造函数和必要 getter 的显式类?

Java 记录

评论

14赞 Mark Rotteveel 11/16/2023
引用 JEP 395: Records:“使用记录增强 Java 编程语言,记录是充当不可变数据透明载体的类JEP 395 总共提到了 86 次“类”和 63 次“类”这两个词。基本上所有的东西(除了原语)都是 Java 中的类,所以记录也是也就不足为奇了。
4赞 Joachim Sauer 11/16/2023
这真的取决于你所说的“句法糖”到底是什么意思,大多数人对他们的实际含义没有一个很好的定义。正如马克所指出的,记录类。但是,如果没有一个明确的定义,它们是否“只是常规类的句法糖”,真的很难回答。
3赞 Mark Rotteveel 11/16/2023
鉴于记录模式(JEP 440:记录模式)仅适用于记录,我想说记录不仅仅是类的语法糖,因为它们提供了“普通”类所不具备的功能。
1赞 ShadowRanger 11/17/2023
我怀疑 s 的独特功能可以由用户定义的类来模拟,只要它们直接继承遵守 s 的所有其他狭隘要求,使该反射能够弄清楚如何解压缩它。特殊声明语法只是为您完成所有工作。Recordjava.lang.RecordRecordRecord
2赞 ShadowRanger 11/17/2023
@supercat:这是一个毫无意义的指导方针?如果JIT优化器可以确定场景的参数,那么它总是可以做一些事情,让它跳过工作(就像C++假设规则一样)。s 的局限性可能会使编译器作者更容易做一些事情,但正如答案所指出的,在引擎盖下,它只是一个具有特定设计的类,唯一独特的是继承自(它自己没有有意义的行为,它只是被序列化和记录模式特别识别)。Recordjava.lang.Record
3赞 Joachim Sauer 11/17/2023
如果你把这个论点推向极端,那么所有的编程语言都只是汇编语言的语法糖(它本身只是机器代码的语法糖,机器代码本身只是内存中位的语法糖,这是......这就是为什么使用“句法糖”的模糊/灵活定义通常毫无意义的原因:你会得到空洞的真实陈述。他们没有,但也没有告诉你任何关于你正在检查的功能的有用信息。

答:

35赞 cvk 11/16/2023 #1

在后台,它仍然会创建一个类(派生自 java.lang.Record)。

您可以自己尝试一下:

// test.java
record Test(int foo, String bar) {}

当你编译它并再次反汇编它时,你会得到以下代码:javac test.javajavap Test

final class Test extends java.lang.Record {
  Test(int, java.lang.String);
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int foo();
  public java.lang.String bar();
}

评论

0赞 supercat 11/17/2023
在机器码级别呢?例如,如果一个函数创建并返回一个具有特定字段的值,而不保留对对象的任何其他引用,并且调用者检索字段并在这样做后放弃对对象的所有引用,那么 JVM 是否能够生成避免创建和放弃对象实例的机器代码?Record
14赞 Joachim Sauer 11/17/2023
Java 不关心机器代码级别,这是 JVM 的实现细节。显然,它不会神奇地利用 CPU 上一些以前未使用的指令或访问以前无法访问的寄存器或内存区域,它们最终只是一种特殊的类。但是,在Java中,通过检查机器代码级别来定义一个特性是否是“语法糖”,就像问如何用光栅电子显微镜检查单个焊接点来构建飞机一样:你会发现一些东西,但你可能错过了整个点。record