Estoy usando The Java® Language Specification Java SE 8 Edition como referencia.
Clase de ejemplo:
class MyClass { void method() { new int[] {0}[0] = 1; } } El código new int[] {0}[0] = 1 debe ser una Asignación , ya que al índice 0 de la matriz creada se le asigna el valor 1 .
Una asignación se compone de LeftHandSide , AssignmentOperator y una expresión. En este ejemplo, LeftHandSide debería ser new int[] {0}[0] .
Un LeftHandSide es un ExpressionName, FieldAccess o ArrayAccess . En este ejemplo, LeftHandSide debería ser un ArrayAccess.
El problema radica en ArrayAccess. ArrayAccess se define como un ExpressionName (no es el caso de este ejemplo) o un PrimaryNoNewArray, y luego una expresión entre paréntesis.
El código new int[] {0} es una ArrayCreationExpression . Una expresión principal es ArrayCreationExpression o PrimaryNoNewArray. Entonces, para mí, parece que el segundo caso para ArrayAccess debería ser Primary y no PrimaryNoNewArray.
Sé que el JLS no tiene una gramática explícita para todo, como Expresiones entre paréntesis o LeftHandSides entre paréntesis, pero esto parece ser un error. Revisé la especificación más reciente (Java SE 17) y la gramática de ArrayAccess no ha cambiado.
Parece que, estrictamente hablando, esto no se ajusta a la gramática especificada. Pero al menos, tiene sentido que un compilador lo permita: la razón por la que se usa PrimaryNoNewArray en lugar de Primary aquí es para que una expresión como new int[1][0] no pueda analizarse ambiguamente como una matriz 2D o como una acceso a la matriz como (new int[1])[0] . Si la matriz tiene un inicializador como new int[]{0}[0] , la sintaxis no es ambigua porque no se puede analizar como si se estuviera creando una matriz 2D.
Dicho esto, dado que JLS no especifica que está permitido, podría tratarse como un detalle de implementación o como un error en el compilador que lo permite.