Der Operator, der hier besprochen wird, wird als Postfix-Inkrementoperator (JLS 15.14.2) bezeichnet. Es wird angegeben, verhalten sich wie folgt:
- Zur Laufzeit, wenn die Auswertung des Operanden Ausdruck abrupt beendet ist, dann wird der Postfix Inkrementausdruck beendet abrupt aus dem gleichen Grund und keine Inkrementierung stattfindet.
- Andernfalls wird dem Wert der Variablen der Wert 1 hinzugefügt und die Summe wird in die Variable zurückgespeichert.
- Vor dem Hinzufügen wird eine binäre numerische Heraufstufung (§5.6.2) für den Wert 1 und den Wert der Variablen ausgeführt.
- Falls erforderlich, wird die Summe durch eine sich verengende primitive Konvertierung (§5.1.3) und/oder Boxing-Konvertierung (§5.1.7) auf den Typ der Variablen beschränkt, bevor sie gespeichert wird.
- Der Wert des Inkrements Postfix Ausdruck ist der Wert der Variablen, bevor der neue Wert gespeichert.
Der letzte Punkt ist der Schlüssel für diese Frage: Der Grund, warum Sie nicht arr[i]++ = v;
tun können, die gleiche genaue Grund, warum Sie nicht x++ = v;
tun können; Der Postfix-Inkrement-Ausdruck gibt einen -Wert zurück, keine Variable.
Von JLS 15.1 Evaluation, Denotation and Result:
Wenn ein Ausdruck in einem Programm ausgewertet wird (ausgeführt), ist das Ergebnis eines von drei Dingen bedeutet:
- Eine Variable [...] (in C, dies wäre ein L-Wert)
- Ein Wert [...]
- Nichts (der Ausdruck wird gesagt, dass void)
genannt
Eine Zuordnung braucht eine Variable auf der linken Seite, und ein Wert ist eine Variable nicht, und das ist, warum Sie nicht x++ = v;
tun können.
Von JLS 15.26 Assignment Operators:
Das Ergebnis des ersten Operanden eines Zuweisungsoperator muß eine Variable sein, oder ein Fehler bei der Kompilierung auftritt. Dieser Operand kann eine benannte Variable [...] oder eine berechnete Variable sein, wie sie sich aus einem [...] Feld oder einem Array-Zugriff ergeben kann. [...]
Der folgende Ausschnitt zeigt fehlerhafte Versuche, einen Wert zuweisen, von eher subtilen geht deutlicher:
int v = 42;
int x = 0;
x = v; // OKAY!
x++ = v; // illegal!
(x + 0) = v; // illegal!
(x * 1) = v; // illegal!
42 = v; // illegal!
// Error message: "The left-hand side of an assignment must be a variable"
Beachten Sie, dass den Postfix Schritt verwenden können Operator irgendwo auf der linken Seite eines Zuweisungsoperators, solange das Endergebnis eine Variable ist.
int[] arr = new int[3];
int i = 0;
arr[i++] = 2;
arr[i++] = 3;
arr[i++] = 5;
System.out.println(Arrays.toString(arr)); // prints "[2, 3, 5]"
Niemals einen solchen Codierungsstil (mit Leerzeichen in eckigen Klammern) in Java-Code gesehen. – Roman
Als eine Randnotiz, der Bytecode für den Operator ++ hängt davon ab, ob es für eine lokale int-Variable verwendet wird oder nicht, und ob das Ergebnis verwendet wird oder nicht. Der einfachste Fall ist das bloße Inkrement einer lokalen int-Variablen, wobei eine einzelne Inkrement-Instruktion erzeugt wird. Wenn Sie ein Array-Member nachträglich inkrementieren, werden einige der komplexesten Bytecodes generiert.(Ich kann keine JIT-Transformation kommentieren.) – Neil