Введение в программирование

       

Приведение ссылочных типов


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

  • приведение;
  • присваивание;
  • вызов метода;
  • выполнение арифметических действий.

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

В языке Java объявление класса определяет одноименный ссылочный тип. Все переменные, имеющие ссылочный тип, указываемый именем класса, являются объектами. Тип такого объекта определяется оператором instanceof.

Например:

String str1; Object ObjectName; ObjectName =(Object) str1; // Приведение типа

if (ObjectName instanceof String) { // Тип объекта String String str2 = (String) ObjectName ; System.out.println(str2); // Запись в стандартный поток // вывода значения строки, // указанной параметром str2 }

В рассмотренном примере тип объекта str1 сначала приводится к типу своего косвенного суперкласса Object, а затем оператором instanceof определяется непосредственный тип объекта (при определении оператором instanceof типа объекта ObjectName как String или Object возвращается значение true).

При приведении ссылочных типов действуют следующие правила:

  • объект всегда может быть приведен к типу своего непосредственного суперкласса;
  • приведение ссылочных типов может выполняться по иерархии классов сколь угодно глубоко;
  • любой класс ссылочного типа всегда можно привести к типу Object.

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

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

Значение простого типа не может быть присвоено значению ссылочного типа, как и значение ссылочного типа не может быть присвоено значению простого типа.

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


Например:

public class A { int x, y; } public class ADerived extends A { int z; } public interface B { void setColor(int color); } public class AB extends A implements B { int color; public void setColor(int color) { this.color = color; } } class MyA{ public static void main(String[ ] args) { // Создание переменных ссылочного типа // и присваивание им значения: A p = new A(); p = new ADerived(); // Правильно: ADerived это // подкласс класса A ADerived p3d = p; // Ошибка

// Присваивание значения переменной // типа Object: Object o = p; // Правильно: любой объект приводим // к типу Object int[ ] a = new int[3]; Object o2 = a; // Правильно: массив приводим к Object

// Присваивание значения переменной // типа интерфейса: AB cp = new AB(); B c = cp; // Правильно: AB реализует интерфейс B

// Присваивание значения переменной // типа массива: byte[ ] b = new byte[4]; a = b; // Ошибка: это массивы различных типов ADerived[ ] p3da = new ADerived[3]; A[ ] pa = p3da; // Правильно: ADerived подкласс класса A p3da = pa; // Ошибка, т.к. необходимо приведение } }

Преобразование приведением является более общим: если преобразование возможно, то приведение может его выполнить. Часто следует явно указывать преобразование приведением, чтобы компилятор имел строгую информацию о типе объекта. Для любого типа значения времени компиляции всегда можно выполнить приведение к тому же самому типу. Это позволит точно указать, что результирующее значение будет иметь именно указанный тип.

Приведением можно преобразовывать значения одного вычислимого типа к другому. Тип boolean не может быть приведен ни к какому другому типу.

Значения простых типов не могут быть приведены к значениям ссылочных типов и наоборот.


Содержание раздела