public static Random rand = new Random(47), public static void main(String[] args) throws Exception { Class initable = Initable class. System out printin("После создания ссылки Initable"). // He приводит к инициализации System out println(Initable.staticFinal). // Приводит к инициализации-System out printin(Initable staticFinal2); // Приводит к инициализации System out println(Initable2 staticNonFinal). Class initable3 = Class forName("Initable3"). System out printlnC"После создания ссылки Initable3"). System out pri ntin(Initable3 staticNonFinal),
}
} /* Output
После создания ссылки Initable 47
Инициализация Initable 258
Инициализация Ini table2 147
Инициализация Initable3 После создания ссылки Ini tablеЗ 74 *///•-
По сути, инициализация откладывается настолько, насколько это возможно. Из результатов видно, что простое использование синтаксиса .class для получения ссылки на класс не приводит к выполнению инициализации. С другой стороны, вызов Class.forNames() немедленно инициализирует класс для получения ссылки на Class, как мы видим на примере initable3.
Параметризованные ссылки
Объект Class используется для создания экземпляров класса и содержит полный код методов этих экземпляров. Кроме того, в нем содержатся статические члены класса. Таким образом, ссылка на Class подразумевает точный тип того, на что она указывает — на объект класса Class.
Однако проектировщики Java SE5 решили предоставить возможность уточнения записи посредством ограничения типа объекта Class, на который может указывать ссылка; для этой цели применяется синтаксис параметризации. В следующем примере верны оба варианта синтаксиса:
// typeinfo/GenericClassReferences java
public class GenericClassReferences {
public static void main(String[] args) { Class intClass = int.class, Class
// genericIntClass = double class; // Недопустимо
}
} ///;-
Если обычная ссылка на класс может быть связана с любым объектом Class, параметризованная ссылка может связываться только с объектами типа, указанного при ее объявлении. Синтаксис параметризации позволяет компилятору выполнить дополнительную проверку типов.
Новый синтаксис преобразования
В Java SE5 также появился новый синтаксис преобразования ссылок на Class, основанный на методе cast():
II typeinfo/ClassCasts java
class Building {}
class House extends Building {}
public class ClassCasts {
public static void main(String[] args) { Building b = new HouseO; Class
}
Метод cast() получает объект-аргумент и преобразует его к типу ссылки на Class. Конечно, при взгляде на приведенный код может показаться, что он занимает слишком много места по сравнению с последней строкой main(), которая делает то же самое. Новый синтаксис преобразования полезен в тех ситуациях, когда обычное преобразование
Другая новая возможность — Class.asSubclass() — вообще не встречается в библиотеке Java SE5. Этот метод позволяет преобразовать объект класса к более конкретному типу.
Проверка перед приведением типов
Итак, мы рассмотрели следующие формы RTTI:
• Классическое преобразование; аналог выражения «(Shape)», которое проверяет, «законно» ли приведение типов в данной ситуации, и в случае неверного преобразования возбуждает исключение ClassCastException.
• Объект Class, представляющий тип вашего объекта. К объекту Class можно обращаться для получения полезной информации во время выполнения программы.