Автоматическое повышение типа в выражениях


Кроме операций присваивания определенное преобразование типов может выполняться также в выражениях. Для примера рассмотрим следующую ситуацию. Иногда в выражениях в целях обеспечения необходимой точности промежуточное значение может выходить за пределы допустимого диапазона любого из операндов. Например, рассмотрим следующее выражение:

byte а = 40;
byte b = 50;
byte с = 100;
int d = а * b / с;

Результат вычисления промежуточного члена а*b вполне может выйти за пределы диапазона допустимых значений его операндов типа byte. Для решения подобных проблем при вычислении выражений Java автоматически повышает тип каждого операнда byte или short до int. То есть вычисление промежуточного выражения а*b выполняется с применением целочисленных значений, а не байтов. Поэтому результат промежуточного выражения 50 * 40, равный 2000, оказывается допустимым, несмотря на то, что и для а и для b задан тип byte.

Хотя автоматическое повышение типа очень удобно, оно может приводить к досадным ошибкам во время компиляции. Например, следующий внешне абсолютно корректный код приводит к возникновению проблемы:

byte b = 50;
b = b * 2;
// Ошибка! Значение типа int не может быть присвоено
// переменной типа byte!

Код предпринимает попытку повторного сохранения произведения 50 * 2 — совершенно допустимого значения типа byte — в переменной типа byte. Однако, поскольку во время вычисления выражения тип операндов был автоматически повышен до int, тип результата также был повышен до int. Таким образом, теперь результат выражения имеет тип int, который не может быть присвоен переменной типа byte без приведения типа. Сказанное справедливо даже тогда, когда, как в данном конкретном случае, значение, которое должно быть присвоено, умещается в переменной целевого типа.

В тех случаях, когда последствия переполнения понятны, следует использовать явное приведение типов вроде:

byte b = 50;
b = (byte) (b * 2) ;

которое приводит к правильному значению, равному 100.