Чтение онлайн

на главную - закладки

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

Явное приведение. В этом случае явно указывается, к какому типу требуется привести исходное значение. Допускаются все виды преобразований, кроме приведений к строке и запрещенных. Может возникать ошибка времени исполнения программы.

Оператор конкатенации производит преобразование к строке своих аргументов.

Числовое расширение (numeric promotion). Числовые операции могут потребовать изменения типа аргумента(ов). Это преобразование имеет особое название - расширение (promotion), так как выбор целевого типа может зависеть не только от исходного значения, но и от второго аргумента операции.

Рассмотрим все случаи более подробно.

Присвоение значений

Такие ситуации неоднократно применялись в этой лекции для иллюстрации видов преобразования. Приведение может потребоваться, если переменной одного типа присваивается значение другого типа. Возможны следующие комбинации.

Если сочетание этих двух типов образует запрещенное приведение, возникнет ошибка. Например, примитивные значения нельзя присваивать объектным переменным, включая следующие примеры:

// пример вызовет ошибку компиляции

// примитивное значение нельзя

// присвоить объектной переменной

Parent p = 3;

// приведение к классу-"обертке"

// также запрещено

Long a=5L;

// универсальное приведение к строке

// возможно только для оператора +

String s="true";

Далее, если сочетание этих двух типов образует расширение (примитивных или ссылочных типов), то оно будет осуществлено автоматически, неявным для разработчика образом:

int i=10;

long a=i;

Child c = new Child;

Parent p=c;

Если же сочетание оказывается сужением, то возникает ошибка компиляции, такой переход не может быть проведен неявно:

// пример вызовет ошибку компиляции

int i=10;

short s=i;

// ошибка! сужение!

Parent p = new Child;

Child c=p;

// ошибка! сужение!

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

int i=10;

short s=(short)i;

Parent p = new Child;

Child c=(Child)p;

Более подробно явное сужение рассматривается ниже.

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

byte b=1;

short s=2+3;

char c=(byte)5+'a';

В первой строке переменной типа byte присваивается значение целочисленного литерала типа int, что является сужением. Во второй строке переменной типа short присваивается результат сложения двух литералов типа int, а тип этой суммы также int. Наконец, в третьей строке переменной типа char присваивается результат сложения числа 5, приведенного к типу byte, и символьного литерала.

Однако все эти примеры корректны. Для удобства разработчика компилятор проводит дополнительный анализ при присвоении значений переменным типа byte, short и char. Если таким переменным присваивается величина типа byte, short, char или int, причем ее значение может быть получено уже на момент компиляции, и оказывается, что это значение укладывается в диапазон типа переменной, то явного приведения не требуется. Если бы такой возможности не было, пришлось бы писать так:

byte b=(byte)1;

// преобразование необязательно

short s=(short)(2+3);

// преобразование необязательно

char c=(char)((byte)5+'a');

// преобразование необязательно

// преобразование необходимо, так как

// число 200 не укладывается в тип byte byte b2=(byte)200;

Вызов метода

Это приведение возникает в случае, когда вызывается метод с объявленными параметрами одних типов, а при вызове передаются аргументы других типов. Объявление методов рассматривается в следующих лекциях курса, однако такой простой пример вполне понятен:

// объявление метода с параметром типа long

void calculate(long l) {

...

}

void main {

calculate(5);

}

Как видно, при вызове метода передается значение типа int, а не long, как определено в объявлении этого метода.

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

// пример вызовет ошибку компиляции

void calculate(long a) {

...

}

void main {

calculate(new Long(5));

// здесь будет ошибка

}

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

void calculate(int a) {

...

}

void main {

long a=5;

// calculate(a);

// сужение! так будет ошибка.

calculate((int)a);

// корректный вызов

}

Наконец, в случае расширения, компилятор осуществит приведение сам, как и было показано в примере в начале этого раздела.

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

// пример вызовет ошибку компиляции

// объявляем перегруженные методы

// с аргументами (byte, int) и (short, short)

int m(byte a, int b) { return a+b;}

int m(short a, short b) { return a-b;}

Поделиться:
Популярные книги

Царь царей

Билик Дмитрий Александрович
9. Бедовый
Фантастика:
фэнтези
мистика
5.00
рейтинг книги
Царь царей

Законы Рода. Том 14

Андрей Мельник
14. Граф Берестьев
Фантастика:
аниме
фэнтези
эпическая фантастика
5.00
рейтинг книги
Законы Рода. Том 14

Имя нам Легион. Том 9

Дорничев Дмитрий
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 9

Точка Бифуркации VI

Смит Дейлор
6. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации VI

Барон не играет по правилам

Ренгач Евгений
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон не играет по правилам

Студиозус

Шмаков Алексей Семенович
3. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус

Лекарь Империи 9

Карелин Сергей Витальевич
9. Лекарь Империи
Фантастика:
городское фэнтези
аниме
боевая фантастика
5.00
рейтинг книги
Лекарь Империи 9

Цикл "Идеальный мир для Лекаря". Компиляция. Книги 1-30

Сапфир Олег
Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Цикл Идеальный мир для Лекаря. Компиляция. Книги 1-30

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Первый среди равных. Книга VIII

Бор Жорж
8. Первый среди Равных
Фантастика:
аниме
фантастика: прочее
эпическая фантастика
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга VIII

Отморозок 5

Поповский Андрей Владимирович
5. Отморозок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Отморозок 5

Император Пограничья 4

Астахов Евгений Евгеньевич
4. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 4

На границе империй. Том 10. Часть 9

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 9

Отморозок 4

Поповский Андрей Владимирович
4. Отморозок
Фантастика:
попаданцы
фантастика: прочее
5.00
рейтинг книги
Отморозок 4