C风格的数组不再适用于记录。

22

我之前使用这个人为编造的代码

record Foo(int bar[]) {}

现在,随着Java 16中记录的正式发布,使用C风格数组符号的代码不再编译。以下是来自jshell的输出:

jshell> record Foo(int bar[]) {}
|  Error:
|  legacy array notation not allowed on record components
|  record Foo(int bar[]) {}
|                    ^

Java 15中为什么能编译通过,这是一个bug吗?出于好奇,为什么它不在records中得到支持,而在Java的其他任何地方都得到了支持?

我正在使用Adoptium(基于OpenJDK)中的javac


4
出于好奇,为什么你要使用 C 风格的数组表示法? - MC Emperor
1
@MCEmperor 实际上,这是一个朋友发现的,我认为在SO上分享这个信息会很棒。 - Zabuzard
1个回答

31

解释

C风格的数组表示法被认为是旧式的,并且他们正在尝试在新的结构上尽可能淡化它(不能在旧的结构上进行改变以保持向后兼容性)。

关于这个决定的确切原因,您必须询问实际的开发人员。


错误

事实上,它在Java 15中运行是一个错误。 实际上,规范甚至不允许此操作,即使对于Java 15也是如此,但这种情况被忽视了,并且javac意外地支持了它。

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

您可以在此处阅读更多信息:


JLS定义

不允许这种表示法的JLS部分可以在JLS §8.10.1中找到,其中定义了RecordComponent的语法。

RecordComponent:
  {RecordComponentModifier} UnannType Identifier
  VariableArityRecordComponent 

随着

VariableArityRecordComponent:
  {RecordComponentModifier} UnannType {Annotation} ... Identifier

RecordComponentModifier:
  Annotation

3
可能是在意识到需要复制粘贴编辑之前,从其他地方重用了解析器定义的片段。 - chrylis -cautiouslyoptimistic-
8
这个解释是准确的:C语言风格的数组标记被认为是遗留的,不会被带入新的结构中。我们在进行局部变量类型推断时就已经面对了这个问题;C语言风格的数组会为该特性增加不必要的复杂度(例如,var x[] = ...)。尝试完全淘汰它可能会带来更多的干扰,而收益较小。 - Brian Goetz
1
考虑到JDK代码本身中使用了数百万个遗留语法,这确实会非常具有破坏性。另一方面,被迫浏览代码会有机会注意到该代码中的其他问题。 - Holger

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