В табл. 6.1 приведено резюме по типам, определенным в Java. Только примитивные данные и ссылочные значения можно сохранить в переменных. Порождать объект могут только классы и массивы.
Таблица 6.1. Типы и значения
Типы | Значения |
---|---|
Примитивные типы данных | значения примитивов |
Класс, интерфейс, типы массивов (ссылочные типы) | ссылочные значения |
Массивы в Java являются объектами. Типы массивов (boolean[]
, Object[]
, StackImp[]
) неявно образуют иерархию наследования. Иерархия наследования изображения на рис.6.3, может быть дополнена соответствующими типами массивов. Итоговая иерархия типов показана на рис. 6.4. Тип массива показан как «класс» с обозначением []
, добавленным к имени типа элемента. Класс SafeStackImpl
— это подкласс класса StackImpl
. Соответствующие типы массивов, SafeStackImpl[]
и StackImpl[]
, показаны как подтип и супертип соответственно в этой иерархии. На рис. 6.4 также показаны типы массивов, соответствующие некоторым примитивным типам данных SafsStackImpl
Рис.6.4 Иерархия ссылочного типа
Из иерархии типов на рис. 6.4 мы можем сделать следующие выводы.
Object
. Это применимо к классам, интерфейсам и типам массивов, так как они и есть все ссылочные типы.
Object[]
, но массивы примитивных типов не являются таковыми. Обратите внимание, что тип массива Object[]
является также подтипом типа Object
.
Можно создать массив интерфейсного типа, но от интерфейса нельзя породить объект (как случае с абстрактными классами). В операторе объявления ниже ссылка iSafeStackArray
имеет тип ISafeStack[]
(т.е. массив интерфейсного типа ISafeStack
). Выражение создания массива создает массив, чьи элементы относятся к типу ISafeStack
. Объект массива может содержать пять ссылок типа ISafeStack
. В следующем объявлении эти ссылки не инициализируются.
ISafeStack[] iSafeStackArray = new ISafeStack[5];
Ссылка на массив обладает полиморфным поведением, как любая другая ссылка с учетом ее расположения в иерархии типов. Однако может быть не к ходим контроль на этапе выполнения, когда объекты добавляются в массив, как показано в следующем примере.
Следующее присваивание допустимо, так как ссылка супертипа (StackStackImp[]
) может указывать на объекты его подтипа (SafeStacklmpl[]
).
StackImpl[] stackImplArray = new SafeStackImpl[2]; // (1)
Поскольку StackImpl
является супертипом SafeStackImpl
, следующее присваивание тоже допустимо.
stackImplArray[0] = new SafeStackImpl(10); // (2)
Присваивание в строке (2) добавляет объект SafeStackImpl
в объект SafeStackImpl[]
(т.е. массив SafeStackImpl
), созданный в (1).
Так как тип массива stackImplArray[i]
, (0 < i < 2)
, — это тип StackImpl
, то должно быть возможно следующее присваивание.
stackImplArray[1] = new StackImpl(20); // (3) Выбросит исключение
На этапе компиляции никаких проблем не возникнет, так как компилятор не может проследить, что переменная массива stackImplArray
реально обозначает во время выполнения объект SafeStackImpl[]
.
Однако присваивание в строке (3) вызывает исключение ArrayStoreException
, которое будет выброшено на этапе выполнения, так как объект SafeStackImpl[]
может содержать объекты типа StackImpl
.
Интерфейсы | Преобразование типов значений ссылок |