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

2022-09-03 15:35:44

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

示例类:

class MyClass {

  void method() {
    new int[] {0}[0] = 1;
  }

}

代码应该是赋值,因为创建的数组的索引被赋值。new int[] {0}[0] = 101

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

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

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

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

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


答案 1

严格来说,这看起来不符合指定的语法。但至少,编译器允许它确实是有意义的:使用而不是这里的原因是,像这样的表达式不能被模棱两可地解析为2D数组或数组访问,比如。如果数组具有类似这样的初始值设定项,则语法没有歧义,因为这不能解析为创建 2D 数组。PrimaryNoNewArrayPrimarynew int[1][0](new int[1])[0]new int[]{0}[0]

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


答案 2

推荐