允许“new int[] {0}[0] = 1;”的Java语法是什么?编译?

Geo*_*off 15 java grammar language-lawyer

我使用Java\xc2\xae 语言规范 Java SE 8 版本作为参考。

\n

示例类:

\n
class MyClass {\n\n  void method() {\n    new int[] {0}[0] = 1;\n  }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该代码new int[] {0}[0] = 1应该是一个赋值,因为0所创建的数组的索引被分配了值1

\n

赋值由LeftHandSide、赋值运算符和表达式组成。在此示例中,LeftHandSide 应为new int[] {0}[0]

\n

LeftHandSide 是 ExpressionName、FieldAccess 或ArrayAccess。在此示例中,LeftHandSide 应该是 ArrayAccess。

\n

问题出在 ArrayAccess 上。ArrayAccess 被定义为 ExpressionName(本示例中不是这种情况)或 PrimaryNoNewArray,然后是括号之间的表达式。

\n

该代码new int[] {0}是一个ArrayCreationExpression。Primary表达式可以ArrayCreationExpression 或 PrimaryNoNewArray。所以对我来说,ArrayAccess 的第二种情况似乎应该是 Primary 而不是 PrimaryNoNewArray。

\n

我知道 JLS 没有针对所有内容的显式语法,例如带括号的表达式或带括号的 LeftHandSides,但这似乎是一个错误。我检查了最新的规范(Java SE 17),ArrayAccess 的语法没有变化。

\n

kay*_*ya3 9

严格来说,这似乎不符合规定的语法。但至少,编译器允许它确实是有意义的:PrimaryNoNewArray使用而不是Primary这里的原因是这样的表达式new int[1][0]不能被模糊地解析为二维数组或数组访问(如 )(new int[1])[0]。如果数组具有像new int[]{0}[0]这样的初始值设定项,则语法不会含糊,因为这不能被解析为创建二维数组。

也就是说,由于 JLS 没有指定它是允许的,因此它可以被视为实现细节或允许它的编译器中的错误。