Преобразование и приведение типов. Автоматическое продвижение типов в выражениях

Преобразование и приведение типов. Автоматическое продвижение типов в выражениях



1. Что такое явное и автоматическое приведение типов в выражениях?

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

Приведение типов может быть явное и автоматическое.

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

При автоматическом приведении типов нужно, чтобы выполнялись два условия:

  • оба типа должны быть совместимыми;
  • длина исходного типа (типа источника) должна быть меньше длины целевого типа (типа приемника).

 

2. Как выглядит явное приведение типов в выражениях? Примеры

Явное приведение типов позволяет осуществлять присвоение несовместимых типов. Общая форма явного приведения типов имеет вид:

(целевой_тип) значение

где

  • целевой_тип – это тип, в который нужно привести указанное значение.

Примеры явного приведения типов.

// явное приведение типов в выражениях
byte b;
int a;
double d;
float f;

d = -39.9203;
a = (int)d;   // a = -39
f = (float)d; // f = -39.9203
b = (byte)d;  // b = -39

d = 302930932;
b = (byte)d; // b = -12 - урезание значения

a = -27;
b = (byte)a; // b = -27

 

3. Примеры автоматического приведения типов

Пример 1. Автоматическое приведение целочисленных типов.

// автоматическое приведение целочисленных типов
int a;
byte b;
short sh;
b = -23;
a = b; // a = -23 - автоматическое приведение типов

sh = -150;
a = sh; // a = -150

long l = 200;
// Ошибка: "Type mismatch: cannot convert from long to int"
// a = l;

l = b;  // l = -23
l = sh; // l = -150

char c = 'Z';
a = c;  // a = 90 - код символа 'Z'

boolean b1 = false;
//a = b1; - ошибка, типы несовместимые

Пример 2. Автоматическое приведение типов с плавающей запятой.

// автоматическое приведение типов с плавающей запятой
float f;
double d;
f = 3.409033f;
d = f; // d = 3.409033

Пример 3. Автоматическое приведение смешанных типов. Такой случай возможен, если переменной типа с плавающей запятой присваивается значение переменной целочисленного типа.

// автоматическое приведение смешанных типов
float f;
double d;
int a;
a = 28;
d = a; // d = 28.0
f = a; // f = 28.0

// Ошибка: Type mismatch: cannot convert from float to int
// a = f;

 

4. Как осуществляется автоматическое продвижение типов в выражениях?

Автоматическое продвижение типов происходит в выражениях. При этом, значение, которое фигурируют в выражениях, автоматически продвигаются к типам с большими диапазонами значений.

При автоматическом продвижении типов в выражениях:

  • если один из целочисленных операндов имеет тип int, то все значения типов byte, short и char продвигаются к типу int;
  • если один из целочисленных операндов имеет тип long, то все выражение продвигается к типу long;
  • если один из операндов относится к типу float, то тип всего выражения будет также типа float (если нет операндов типа double);
  • если один из операндов относится к типу double, то тип всего выражения будет также double.

 



5. Пример продвижения из типа byte в int в котором выражение не содержит операндов-переменных типа int (long)
// продвижение типов в выражениях
// byte -> int
byte b;
b = 1000 / 20; // b = 50, работает, так как результат помещается в тип byte

Вышеприведенный пример работает корректно, так как:

  • результат помещается (совместим) в тип byte;
  • нет операндов типа int.

В вышеприведенном примере значения 1000 превышает диапазон значений типа byte. Сначала число 1000 приводится к типу int. Но результат

1000 / 20 = 50

приводится к типу byte и может корректно поместиться в переменной b.

Если написать так:

byte b;
b = 100000 / 20; // ошибка, так как результат не помещается в тип byte

то выйдет ошибка компиляции с выводом сообщения:

Type mismatch: cannot convert from int to byte

В этом случае результат не помещается в тип byte:

100000 / 20 = 5000 

Тогда это число (5000) автоматически становится типом int и компилятор выдаст сообщение об ошибке.

Если сделать явное приведение типов:

byte b;
b = (byte) (100000 / 20); // b = -120

то в этом случае результат 5000 типа int превращается в тип byte. Как известно, переменная типа int занимает 32 бита, а переменная типа byte занимает 8 бит. Значение переменной типа int урезается. И имеем то, что имеем (b = -120).

Вышеприведенные примеры относятся и к переменным типов short и char.

 

6. Пример. Продвижение из типа byte в тип int, в котором выражение содержит операнд-переменную типа int
// продвижение типов в выражениях
// byte -> int
byte b;
int d;
d = 20;

// ошибка, результат есть типом int, так как переменная d есть типа int
// b = 1000 / d;

В вышеприведенном примере в выражении используется переменная d типа int. Поэтому компилятор выдаст сообщение об ошибке:

Type mismatch: cannot convert from int to byte

Это означает, что результат есть типа int (а не byte) даже если значение помещается в диапазон значений типа byte. Поскольку в выражении используется переменная-операнд d типа int.

Если осуществить явное приведение типов, то результат будет корректным:

// продвижение типов в выражениях
// byte -> int
byte b;
int d;
d = 20;
b = (byte)(1000 / d); // b = 50 - работает корректно

 

7. Пример. Продвижение из типа int в тип long

Пример продвижения типов из int в long. Если один из операндов есть типа long, то все выражение продвигается к типу long.

int d;
long l;
d = 10000 * 200; // работает, d = 2000000

// Ошибка! Type mismatch: cannot convert from long to int
// d = 1L * 2L; - операнды 1L и 2L есть типа long

l = 100;
// ошибка, один из операндов есть типа long
// d = l * 2;

Как видно из примера, если один из операндов есть типа long, то все выражение становится типа long.

 

8. Пример. Продвижение к типу float

В данном примере показано, что если один из операндов имеет тип float, то все выражение продвигается к типу float (если отсутствует тип double).

int d;
float f;

d = (int)(2.5 * 4); // работает, d = 10, происходит явное приведение с float в int

f = 2.5f;
d = (int)(f * 4); // тоже работает, d = 10

// ошибка: cannot convert from float to int
// d = 2.5f * 4;
// d = f * 4;

 

9. Пример. Продвижение к типу double

В примере показано правило:

  • если один из операндов есть типа double, то тип всего выражения продвигается к типу double.
int a;
float f;
double d;

a = 20;
d = 20.0;

// ошибка: cannot convert from double to float
// f = a + d;
f = (float)(a + d); // работает: f = 40.0

 


Связанные темы