В табл. 6.1 приведено резюме по типам, определенным в Java. Только примитивные данные и ссылочные значения можно сохранить в переменных. Порождать объект могут только классы и массивы.
Типы | Значения |
---|---|
Примитивные типы данных | значения примитивов |
Класс, интерфейс, типы массивов (ссылочные типы) | ссылочные значения |
Массивы в Java являются объектами. Типы массивов (boolean[]
, Object[]
, StackImp[]
) неявно образуют иерархию наследования. Иерархия наследования изображения на рис.6.3, может быть дополнена соответствующими типами массивов. Итоговая иерархия типов показана на рис. 6.4. Тип массива показан как «класс» с обозначением []
, добавленным к имени типа элемента. Класс SafeStackImpl
— это подкласс класса StackImpl
. Соответствующие типы массивов, SafeStackImpl[]
и StackImpl[]
, показаны как подтип и супертип соответственно в этой иерархии. На рис. 6.4 также показаны типы массивов, соответствующие некоторым примитивным типам данных SafsStackImpl
Из иерархии типов на рис. 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
.
Интерфейсы | Преобразование типов значений ссылок |