Иллюстрированный самоучитель по Java
Приведение
типов
Результат арифметической операции
имеет тип 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 нет целочисленного
переполнения.