Приведение типов
Результат арифметической операции имеет тип int, кроме того случая, когда один из операндов типа
long
. В этом случае результат будет типа
long
.
Перед выполнением арифметической операции всегда происходит
повышение
(promotion) типов
byte
,
short
,
char
. Они преобразуются в тип
int
, а может быть, и в тип
long
, если другой операнд типа
long
. Операнд типа
int
повышается до типа
long
, если другой операнд типа
long
. Конечно, числовое значение операнда при этом не меняется.
Это правило приводит иногда к неожиданным результатам. Попытка откомпилировать простую программу, представленную в листинге 1.3, приведет к сообщениям компилятора, показанным на рис. 1.3.
Листинг 1.3.
Неверное определение переменной
class InvalidDef{
public static void main (String [] args) {
byte b1 = 50, b2 = -99;
short k = b1 + b2; // Неверно! '
System.out.println("k=" + k);
}
}
Эти сообщения означают, что в файле InvalidDef.java, в строке 4, обнаружена возможная потеря точности (possible loss of precision). Затем приводятся обнаруженный (found) и нужный (required) типы, выводится строка, в которой обнаружена (а не сделана) ошибка, и отмечается символ, при разборе которого найдена ошибка. Затем указано общее количество обнаруженных (а не сделанных) ошибок (1 error).
Рис. 1.3.
Сообщения компилятора об ошибке
В таких случаях следует выполнить явное приведение типа. В данном случае это будет
сужение
(narrowing) типа
int
до типа
short
. Оно осуществляется операцией явного приведения, которая записывается перед приводимым значением в виде имени типа в скобках. Определение
short k = (short)(b1 + b2)
;
будет верным.
Сужение осуществляется просто отбрасыванием старших битов, что необходимо учитывать для больших значений. Например, определение
byte b = (byte) 300;
даст переменной
b
значение
44
. Действительно, в двоичном представлении числа
300
, равном
100101100
, отбрасывается старший бит и получается
00101100
.
Таким же образом можно произвести и явное
расширение
(widening) типа, если в этом есть необходимость. .
Если результат целой операции выходит за диапазон своего типа
int
или
long
, то автоматически происходит приведение по модулю, равному длине этого диапазона, и вычисления продолжаются, переполнение никак не отмечается.
Замечание
В языке Java нет целочисленного переполнения.