the simple assignment operator的說明書描述了此行爲:
...
如果左邊的操作數是一個數組訪問表達式(§15.10.3),可能包含在一個或多個對圓括號,則:
- 首先,計算左側操作數數組訪問表達式的數組引用子表達式。如果此評估突然完成,則由於相同的原因,分配表達式會突然完成; (左側操作數數組訪問表達式)的索引子表達式和右側操作數不計算,並且不發生任何分配。
這通常完成。
- 否則,左邊的操作數數組訪問表達式的指數的子表達式進行求值。如果此評估突然完成,則由於相同的原因,賦值表達式會突然完成,並且右側的操作數不會被計算並且不會分配。
這通常完成。
- 否則,將評估右側的操作數。如果此評估突然完成,則由於同樣的原因,分配表達式會突然完成,並且不會進行分配。
這突然完成,ArithmeticException
。
- 否則,如果該數組引用子表達式的值爲空,則沒有發生分配和拋出NullPointerException。
這永遠不會被執行。
因此,看起來至少在第15.7.1節的引用中存在不一致或過於簡化。
有趣的是,相同的行爲未對該化合物賦值運算符,例如觀察到的
int[] arr = null;
arr[0] += 1 % 0;
確實產量NullPointerException
。
JLS Sec 15.26.2描述了這一點。這也許較少令人吃驚,但是,因爲:
形式E1 op= E2
的化合物賦值表達式是等效於E1 = (T) ((E1) op (E2))
,其中T
是E1
類型,不同之處在於E1
只計算一次。
換句話說,這個代碼是(大約)等效於:
arr[0] = arr[0] + 1 % 0;
所以NullPointerException
發生在評價右手操作數的簡單賦值的。