Арифметический контекст

Арифметический контекст

В арифметическом контексте с типами данных byte, short, char, int все значения операндов расширяются до int. Если выражение содержит long, то все значения приводятся к long. Если арифметические операции содержат float или double, то значения приводятся к double.


byte one = 1;
byte two = 2;
short result = one + two; // ошибка компиляции: невозможно привести тип int
                         //к типу short без потери точности
Можно либо выполнить явное приведение:


short resultS = (short) (one + two);
Либо сделать переменные one и two финальными. Тогда компилятор будет уверен, что значение 3 можно присвоить переменной типа short без потери точности:


final byte one = 1;
final byte two = 2;
short result = one + two;
Однако, операторы присваивания +=, *= и т. д., а также ++ и -- являются исключениями из этого правила.
Например, если проинкрементировать любую переменную типа short, тип возвращаемого значения будет short.


byte one = 1;
byte two = 2;
short result = 200;
result += one;
two++;
one %= 2;
Операторы присваивания имеют ещё одну особенность: они выполняют неявное приведение типов.
Такой пример вызовет ошибку компиляции:


byte x = 1;
long y = 2;
x = x + y; // ошибка компиляции: невозможно привести long к byte
Но если использовать оператор присваивания +=, то ошибки не будет:


x += y;
System.out.println(x); // 3
Оператор += сначала приведёт x к типу long, выполнит операцию сложения, а потом приведёт результат к типу byte.

Это всё замечательно, но стоит быть осторожным с использованием этого свойства, поскольку неявное приведение типов может приводить к неожиданным результатам:


byte k = 1;
int z = 200;
k *= z;
System.out.println(k); // -56
Типы данных