Почему оператор приращения Java допускает сужение операций без явного приведения?
Возможный дубликат:
Java + = оператор
В Java это недопустимо (не компилируется), как и ожидалось:
long lng = 0xffffffffffffL;
int i;
i = 5 + lng; //"error: possible loss of magnitude"
Но это прекрасно (?!)
long lng = 0xffffffffffffL;
int i = 5;
i += lng; //compiles just fine
Это, очевидно, операция сужения, которая может превышать диапазон int
. Так почему компилятор не жалуется?
Ответы
Ответ 1
i += lng;
оператор присваивания присваивается неявно.
i+=lng;
is same as
i = int(i+lng);
FROM JLS:
Выражение составного присваивания формы E1 op = E2 эквивалентно к E1 = (T) ((E1) op (E2)), где T - тип E1, за исключением того, что E1 оценивается только один раз.
Ответ 2
Это определено в JLS # 15.26.2:
Сложное выражение присваивания формы E1 op= E2
эквивалентно E1 = (T) ((E1) op (E2))
, где T
- тип E1
, за исключением того, что E1
оценивается только один раз.
Другими словами, i += lng
выполняет трансляцию неявно.
Ответ 3
Компилятор не жалуется, потому что, согласно JLS §15.26.2. Операторы присваивания соединений:
Совокупное выражение выражения формы E1 op= E2
эквивалентно E1 = (T) ((E1) op (E2))
, где T
- тип E1
, за исключением того, что E1
оценивается только один раз.
Таким образом,
i += lng;
эквивалентно
i = (int)(i + lng);