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

What is the Java grammar that allows "new int[] {0}[0] = 1;" to compile?

我正在使用 The Java® Language Specification Java SE 8 Edition 作为参考。

示例class:

class MyClass {

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

}

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

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

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

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

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

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

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

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