Урок 3

Преобразование примитивных типов


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

Пример 1. Присвоение значения переменной одного типа другому

int i = 11;
byte b = 22;
i = b;

В Java существует 2 типа преобразований - автоматическое преобразование (неявное) и приведение типов (явное преобразование).

Два типа преобразования в Java

1. Aвтоматическое преобразование

Если оба типа совместимы, их преобразование будет выполнено в Java автоматически. Например, значение типа byte всегда можно присвоить переменной типа int, как это показано в примере 1.

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

  • оба типа должны быть совместимы
  • длина целевого типа должна быть больше длины исходного типа

В этом случае происходит преобразование с расширением

Следующая схема показывает расширяющее преобразование в Java:

Схема совместимых преобразований для примитивных типов в Java

Сплошные линии обозначают преобразования, выполняемые без потери данных. Штриховые линии говорят о том, что при преобразовании может произойти потеря точности.

Например, тип данных int всегда достаточно велик, чтобы хранить все допустимые значения типа byte, поэтому никакие операторы явного приведения типов в данном случае не требуются. С точки зрения расширяющего преобразования числовые типы данных, в том числе целочисленные и с плавающей точкой, совместимы друг с другом. В то же время не существует автоматических преобразований числовых типов в тип char или boolean. Типы char и boolean также не совместимы друг с другом.

Стоит немного пояснить почему, к примеру тип byte не преобразуется автоматически (не явно) в тип char, хотя тип byte имеет ширину 8 бит, а char - 16, тоже самое касается и преобразования типа short в char. Это происходит потому, что byte и short знаковые типы данных, а char без знаковый. Поэтому в данном случае требуется использовать явное приведение типов, поскольку компилятору надо явно указать что вы знаете чего хотите и как будет обрабатываться знаковый бит типов byte и short при преобразовании к типу char.

Поведение величины типа char в большинстве случаев совпадает с поведением величины целого типа, следовательно, значение типа char можно использовать везде, где требуются значения int или long. Однако напомним, что тип char не имеет знака, поэтому он ведет себя отлично от типа short, несмотря на то что диапазон обоих типов равен 16 бит.

2. Приведение типов

Несмотря на все удобство автоматического преобразования типов, оно не в состоянии удовлетворить все насущные потребности. Например, что делать, если значение типа int нужно присвоить переменной типа byte? Это преобразование не будет выполняться автоматически, поскольку длина типа byte меньше, чем у типа int. Иногда этот вид преобразования называется сужающим преобразованием, поскольку значение явно сужается, чтобы уместиться в целевом типе данных.

Чтобы выполнить преобразование двух несовместимых типов данных, нужно воспользоваться приведением типов. Приведение - это всего лишь явное преобразование типов. Общая форма приведения типов имеет следующий вид:

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

где параметр целевой_тип обозначает тип, в который нужно преобразовать указанное значение.

Пример 2. Приведение типов

Например, в следующем фрагменте кода тип int приводится к типу byte:

int i = 11;
byte b = 22;
b = (byte) i;

Преобразования значений с плавающей точкой в целые числа. При этом дробная часть значения с плавающей точкой просто отбрасывается (операция усечения):

Пример 3. Преобразования значений с плавающей точкой в целые числа

double d = 3.89;
int a = (int) d; //Результат будет 3

При приведении более емкого целого типа к менее емкому старшие биты просто отбрасываются.

Пример 4. Преобразования более емкого целого типа к менее емкому целому числу

int i = 323;
byte b = (byte) i; //Результат будет 67

При приведении более емкого значения с плавающей точкой в целое число происходит усечение и отбрасывание старших битов:

Пример 5. Преобразования более емкого значения с плавающей точкой к менее емкому целому числу

double d = 389889877779.89;
short s = (short) d; //Результат будет -1

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

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

В языке Java действуют следующие правила:

  1. Если один операнд имеет тип double, другой тоже преобразуется к типу double.
  2. Иначе, если один операнд имеет тип float, другой тоже преобразуется к типу float.
  3. Иначе, если один операнд имеет тип long, другой тоже преобразуется к типу long.
  4. Иначе оба операнда преобразуются к типу int.
  5. В выражениях совмещенного присваивания (+=,-=,*=,/=) происходит автоматическое расширение типов, а затем уже неявное приведение типов.

 Приведем пример:

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

byte b1 = 1;
byte b2 = 2 * b1; //Ошибка компиляции
int i1 = 2 * b1;
b2 *= 2;

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

public class IntegerDemo1 {
    public static void main(String[] args) {
        byte b1 = 50, b2 = -99;
        short k = b1 + b2; //ошибка компиляции
        System.out.println("k=" + k);
    }
}

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

public class IntegerDemo2 {
    public static void main(String[] args) {
        byte b1 = 50, b2 = -99;
        b1 += b2;
        System.out.println("b1=" + b1);
    }
}

 

Источники:

1. http://pr0java.blogspot.com/2015/12/java.html

2. https://vertex-academy.com/tutorials/ru/prividenie-tipov-v-java/

3. Герберт Шилдт. Java 8. Руководство для начинающих. Глава 3. Типы данных переменные и массивы



0 comments
Leave your comment: