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


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

i += j;

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

i = i + j;

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

int i = 5;
long j = 8;

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

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


3252


источник


Ответы:


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

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


2189



Хорошим примером этого литья является использование * = или / =

byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57

или

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

или

char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'

или

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

438



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

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

short x = 3;
x += 4.6;

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

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

221



Да,

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

i += l; 

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

i = (int)(i + l);

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

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


163



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

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


85



Проблема здесь связана с литьем типов.

Когда вы добавляете int и long,

  1. Объект int заносится в long и оба добавляются, и вы получаете длинный объект.
  2. но длинный объект не может быть неявным образом передан в int. Итак, вы должны сделать это явно.

Но +=закодирован таким образом, что он набирает тип. i=(int)(i+m)


56



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

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

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


46



Sometimes, such a question can be asked at an interview.

For example, when you write:

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

there is no automatic typecasting. In C++ there will not be any error compiling the above code, but in Java you will get something like Incompatible type exception.

So to avoid it, you must write your code like this:

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

37



The main difference is that with a = a + b, there is no typecasting going on, and so the compiler gets angry at you for not typecasting. But with a += b, what it's really doing is typecasting b to a type compatible with a. So if you do

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

What you're really doing is:

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

18



Subtle point here...

There is an implicit typecast for i+j when j is a double and i is an int. Java ALWAYS converts an integer into a double when there is an operation between them.

To clarify i+=j where i is an integer and j is a double can be described as

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

See: this description of implicit casting

You might want to typecast j to (int) in this case for clarity.


7