C 样式数组不再处理记录

Zab*_*uza 9 java arrays java-record java-15 java-16

我以前使用过这个人为的代码

record Foo(int bar[]) {}
Run Code Online (Sandbox Code Playgroud)

这是利用 C 风格的数组符号。它在 Java 15 中编译得很好。

现在,突然之间,随着Java 16中记录的正式发布,它不再编译了。这是jshell的输出:

record Foo(int bar[]) {}
Run Code Online (Sandbox Code Playgroud)

为什么它在 Java 15 中编译,这是一个错误吗?出于好奇,为什么它在记录中不受支持,而在 Java 的其他任何地方都受支持?

我正在使用javac来自Adoptium(基于 OpenJDK)。

Zab*_*uza 14

解释

C 风格的数组表示法被认为是遗留的,似乎他们试图在可能的情况下在新构造上淡出它(不能更改旧构造上的改造以不降低向后兼容性)。

您必须向实际开发人员询问此决定背后的确切原因。


漏洞

它在 Java 15 中工作的事实确实是一个错误。规范实际上不允许它,即使对于 Java 15 也是如此,但这被忽略并javac意外地支持它。

他们注意到了它并在 Java 16 中修复了它,因此它不再编译。

你可以在这里读更多关于它的内容:


JLS定义

JLS 中不允许使用符号的部分可以在JLS §8.10.1 中找到,其中将RecordComponents的语法定义为:

RecordComponent:
  {RecordComponentModifier} UnannType Identifier
  VariableArityRecordComponent 
Run Code Online (Sandbox Code Playgroud)

VariableArityRecordComponent:
  {RecordComponentModifier} UnannType {Annotation} ... Identifier
Run Code Online (Sandbox Code Playgroud)

RecordComponentModifier:
  Annotation
Run Code Online (Sandbox Code Playgroud)

  • 这个解释是准确的;C 风格的数组表示法被认为是遗留的,不会被继承到新的结构中。我们之前在进行局部变量类型推断时就遇到过这个问题;C 风格的数组会使功能变得复杂,但没有什么好处(例如“var x[] = ...”)。试图完全淘汰它可能会带来更多的破坏,而不是其价值。 (8认同)
  • 在意识到他们需要复制和粘贴编辑之前,可能从其他地方重用了解析器定义的片段。 (3认同)