java - Почему операторам Java + =, - =, * =, / = сложного присваивания не требуется кастинг?




5 Answers

Как всегда с этими вопросами, JLS держит ответ. В этом случае §15.26.2. Операторы присвоения соединения . Экстракт:

Составляющее выражение присваивания формы E1 op= E2 эквивалентно E1 = (T)((E1) op (E2)) , где T - тип E1 , за исключением того, что E1 оценивается только один раз.

Пример, приведенный в п. 15.26.2

[...] правильный код:

short x = 3;
x += 4.6;

и приводит к тому, что x имеет значение 7, потому что оно эквивалентно:

short x = 3;
x = (short)(x + 4.6);

Другими словами, ваше предположение верно.

До сегодняшнего дня я думал, что, например:

i += j;

Был просто ярлык для:

i = i + j;

Но если мы попробуем это:

int i = 5;
long j = 8;

Тогда i = i + j; не будет компилироваться, но i += j; будет компилировать штраф.

Означает ли это, что на самом деле i += j; является ярлыком для чего-то вроде этого i = (type of i) (i + j) ?




Очень хороший вопрос. Спецификация языка Java подтверждает ваше предложение.

Например, следующий код верен:

short x = 3;
x += 4.6;

и приводит к тому, что x имеет значение 7, потому что оно эквивалентно:

short x = 3;
x = (short)(x + 4.6);



вам нужно использовать от long до int explicitly в случае i = i + l тогда он будет компилировать и давать правильный результат. лайк

i = i + (int)l;

или же

i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

но в случае += он просто отлично работает, потому что оператор неявно выполняет литье типов от типа правильной переменной до типа левой переменной, поэтому не нужно явно указывать.




Преобразование типа Java выполняется автоматически, когда тип выражения в правой части операции присваивания можно безопасно продвигать к типу переменной в левой части задания. Таким образом, мы можем смело назначить:

 byte -> short -> int -> long -> float -> double. 

То же самое не будет работать наоборот. Например, мы не можем автоматически преобразовать long в int, потому что первое требует большего объема памяти, чем второе, и, следовательно, информация может быть потеряна. Чтобы заставить такое преобразование, мы должны выполнить явное преобразование.
Тип - конверсия




Основное различие заключается в том, что при a = a + b не происходит никакого приведения типов, и поэтому компилятор сердится на вас за то, что он не типизируется. Но с a += b , что он действительно делает, - это приведение типа b к типу, совместимому с a . Так что если вы это сделаете

int a=5;
long b=10;
a+=b;
System.out.println(a);

То, что вы действительно делаете, это:

int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);



Related