此處討論的運算符稱爲後綴增量運算符(JLS 15.14.2)。它被指定到的行爲如下:
- 在運行時,如果操作數表達式的計算突然完成,那麼後綴遞增表達突然完成出於同樣的原因,並沒有增量發生。
- 否則,將值1添加到變量的值中,並將總和存回變量。
- 在添加之前,對值1和變量的值執行二進制數值提升(第5.6.2節)。
- 如有必要,總和通過縮小原始轉換(§5.1.3)和/或受到裝箱轉換(§5.1.7)變爲存儲前的變量類型。
- 後綴增量表達式的值是存儲新值之前的變量的值。
最後一點是這個問題的關鍵是:你爲什麼不能做arr[i]++ = v;
的道理是一樣的確切原因,爲什麼你不能這樣做x++ = v;
;後綴增量表達式返回值,而不是變量。
從JLS 15.1 Evaluation, Denotation and Result:
當在程序中的表達式求值(執行),所述結果表示三種情況之一:
- 可變[...](在C,這將被稱爲左值)
- 值[...]
- 無(表達被認爲是無效)
的分配需要在左手側的可變和值不是一個變量,這就是爲什麼你不能這樣做x++ = v;
。
從JLS 15.26 Assignment Operators:
賦值操作符的第一操作數的結果必須是一個變量或編譯時錯誤發生。這個操作數可能是一個命名變量[...],或者它可能是一個計算變量,可能來自字段或數組訪問。 [...]
下面的代碼片段顯示錯誤嘗試分配給值,從相當微妙要更明顯:
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"
請注意,您可以使用的後綴遞增運算符某處位於賦值運算符的左側,只要最終結果是一個變量。
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]"
在java代碼中從來沒有見過這種編碼風格(帶方括號內的空格)。 – Roman 2010-03-14 20:31:11
作爲一個方面說明,++運算符的字節碼取決於它是否用於本地int變量,以及是否使用結果。最簡單的情況是生成一個本地int變量的簡單增量,在該變量中生成單個增量指令。你在提交數組成員後會生成一些最複雜的字節碼。(我不能評論任何JIT轉換。) – Neil 2010-03-14 21:54:32