Преобразования ссылочных типов

Открыта
Преобразования ссылочных типов - 1

— А теперь небольшой урок от Диего. Кратко и по существу о преобразовании ссылочных типов.

— Начнем мы пока только с переменной типа Object. Этой переменной можно присвоить ссылку любого типа (расширение типа). Но чтобы выполнить обратное присваивание (сужение типа) приходится явно указывать операцию приведения:

Код Описание
String s = "mama";
Object o = s;  // o хранит String
Типичное расширение ссылочного типа
Object o = "mama";// o хранит String
String s2 = (String) o;
Типичное сужение ссылочного типа.
Integer i = 123;  //o хранит Integer
Object o = i;
Расширение типа.
Object o = 123;  //o хранит Integer
String s2 = (String) o;
Ошибка во время исполнения!
Невозможно привести ссылку на число к ссылке на строку.
Object o = 123;  //o хранит Integer
Float s2 = (Float) o;
Ошибка во время исполнения!
Невозможно привести ссылку на целое число к ссылке на дробное число.
Object o = 123f;  // o хранит Float
Float s2 = (Float) o;
Приведение к своему типу. Операция сужения ссылочного типа.

— При расширении или сужении ссылочных типов никакого изменения объекта не происходит. Сужающей (или расширяющей) является именно операция присваивания, при которой, либо выполняется «проверка соответствия типов переменной и ее нового значения» либо нет.

— Тот редкий пример, когда все ясно и понятно.

— Чтобы не было ошибок, как в примерахесть способ узнать, какой именно тип сохранили в переменную типа Object:

Код
int i = 5;
float f = 444.23f;
String s = "17";
Object o = f;                       //o хранит объект типа Float

if (o instanceof  Integer)
{
    Integer i2 = (Integer) o;
}
else if (o instanceof  Float)
{
    Float f2 = (Float) o;            //отработает именно этот if
}
else if (o instanceof  String)
{
    String s2 = (String) o;
}
12
Задача
Java Syntax,  10 уровень,  6 лекция
Недоступна
Набираем код
Внимание! Объявляется набор кода на JavaRush. Для этого включите режим повышенной внимательности, расслабьте пальцы, читайте код и… набирайте его в соответствующем окошке. Набор кода — вовсе не бесполезное занятие, как может показаться на первый взгляд: благодаря ему новичок привыкает к синтаксису и запоминает его (современные IDE редко дают ему это сделать).

— Желательно выполнять такую проверку перед каждым сужением типа, если тип сохраненного объекта на 100% не известен.

— Понятно.

Комментарии (41)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Artificial Intelligence16 уровень, Москва
28 июня, 07:13
Где же is и as? Эх... Хоть на Korlin они есть.
Алексей Ворожцов17 уровень, Нижний Новгород
16 марта, 05:05
Я один не догоняю практическое применение всего этого приведения типов?
Eugene16 уровень
12 апреля, 18:11
Я тоже не понимаю, какой смысл
Ваня Петило15 уровень, Львов
7 июля, 21:23
Иногда оно может потребоваться. Это может быть как редкостью, так и встречаться почти в каждом методе, зависит от характера кода, программы. Это из личного опыта, есть пара мини-проектов, сделанных "в тумбочку". К примеру, без приведения типов вы не напишете даже банальный калькулятор. Чтобы он был точным - вам нужно считать дробные числа тоже. А если пользователь захочет разделить 5 на 3,1634? Целое число на дробное. Джава будет ругаться или банально отбросит всю дробную часть. Вам надо будет проверять, какого типа вводные данные от пользователя и сводить их к тому единственному, с которым вы работаете.
11 января, 10:07
В задаче набираем код название переменной вместо
Float f2 = (Float) o;
написано
Float f = (Float) o;
Николай25 уровень
22 января, 20:06
Никогда не пропускайте набивание кода - руки должны вбивать код, голова понимать, что он делает, а мозг запоминать команды, операции и стиль кода.
Volodymyr Shved18 уровень, Одесса
22 декабря 2018, 06:40
Тот редкий пример, когда все ясно и понятно.
Den17 уровень, Одесса
8 ноября 2018, 19:22
почему так есть ошибка
Integer x =123;
Float fl = (Float) x;
а так нет
Integer x =123;
float fl = (float) x;
Vladimir Dmitriev23 уровень, Минск
10 ноября 2018, 20:35
потому что в первом случае мы пытаемся ОБЪЕКТУ типа Float присвоить ссылку на ОБЪЕКТ типа Integer. Если сделать проверку на инстанс, то будет фолс. во втором же случае данные примитивные. Мы просто присваиваемой притивной переменной значение которое возвращает ссылка на обьект Integer.
shteynu18 уровень
21 декабря 2018, 13:27
В данном случае я бы еще почитал про оберточые классы.
Вадим А28 уровень
16 июня 2018, 11:17
Качаем!)
Rihard198533 уровень
8 июня 2018, 22:31
Впервые в жизни вижу диего без задач))
Pavel Mankevich19 уровень, Limerick
13 апреля 2018, 14:34
Pomenyaite mestami shuzhenie i rashirenie.
Ксюха Бышевая10 уровень, Киев
12 апреля 2018, 20:10
— Начнем мы пока только с переменной типа Object. Этой переменной можно присвоить ссылку любого типа (сужение типа). Но чтобы выполнить обратное присваивание (расширение типа) приходится явно указывать операцию приведения: Судя по примеру, как раз наоборот: при сужении нужно указывать операцию приведения. Это вы напутали или я туплю?)
Павел Корчагин21 уровень, Москва
10 июля 2018, 15:29
Так и есть. Тоже на этом заострил свое внимание
Евгений Мусиевский19 уровень, Киев
1 апреля, 23:47
Не думаю, что здесь напутали. Скорее, не совсем точно объяснили. Когда мы присваиваем экземпляр любого класса (объект) переменной типа Object, то и сам объект сужается до типа Object. Через ссылку такого типа мы можем использовать только методы класса Object. Когда же мы явно приводим ссылку на объект к переменной соответствующего типа, то объект обратно получает доступ ко всем своим методам (расширяется) через эту самую ссылку. Более наглядные примеры можете прочитать в книге Head First Java (8 глава).
Сергей30 уровень
30 декабря 2017, 11:53
увидел Диего, подумал - ну вот. ща будут задачи )) Диего такой непредсказуемый