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




присваивание в java (8)

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

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

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

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

i += j;

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

i = i + j;

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

int i = 5;
long j = 8;

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

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


Да,

в основном, когда мы пишем

i += l; 

компилятор преобразует это в

i = (int)(i + l);

Я просто проверил код файла .class .

Действительно хорошая вещь, чтобы знать


Как всегда с этими вопросами, 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);

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


Иногда такой вопрос можно задать на собеседовании.

Например, когда вы пишете:

int a = 2;
long b = 3;
a = a + b;

нет автоматического приведения типов. В C ++ не будет никакой компиляции ошибки, описанной выше, но в Java вы получите что-то вроде Incompatible type exception .

Чтобы избежать этого, вы должны написать свой код следующим образом:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting

вам нужно использовать от 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.

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


Основное различие заключается в том, что при 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);

Тонкая точка здесь ...

Существует неявный typecast для i+j когда j является double, а i - int. Java ALWAYS преобразует целое число в double при выполнении операции между ними.

Чтобы прояснить i+=j где i - целое число, а j - двойное, можно описать как

i = <int>(<double>i + j)

См. Это описание неявного литья

В этом случае вам может потребоваться приведение типа j к (int) для ясности.


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

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

short x = 3;
x += 4.6;

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

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




assignment-operator