允许"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 没有指定它是允许的,因此它可以被视为实现细节或允许它的编译器中的错误。
我正在使用 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 没有指定它是允许的,因此它可以被视为实现细节或允许它的编译器中的错误。