Getting next Double from q2: 0.0 Getting next Double from q2: 0.5 Getting next Double from q2: 1.0 Getting next Double from q2: 1.5 Getting next Double from q2: 2.0 Попытайтесь самостоятельно сделать обобщенными классы CircularQueue и DynQueue, созданные в примере для опробования 8.1. ## Базовые типы и устаревший код Обобщенные типы появились лишь в версии JDK 5, поэтому в Java нужно было принять меры для обеспечения совместимости с созданным ранее и впоследствии устаревшим кодом. Короче говоря, устаревший код нужно было оставить вполне работоспособным и совместимым с обобщениями. А это означало, что устаревший код должен был нормально взаимодействовать с обобщениями, и наоборот. Для обеспечения перехода к обобщенным типам в Java предусмотрена возможность создания обобщенных классов, используемых без указания аргументов типа. Это подразумевает создание для класса базового типа, иногда еще называемого сырым. Такой тип совместим с устаревшим кодом, в котором ничего не известно об обобщенных классах. Единственный недостаток базового типа заключается в том, что при его использовании теряются преимущества типовой безопасности, присущие обобщениям. Ниже приведен пример программы, демонстрирующий применение базового типа.

// Применение базового типа, class Gen { Т ob; // объявить объект типа Т // передать конструктору ссылку на объект типа Т Gen(Т о) { ob = о; } // возвратить объект ob Т getob { return ob; }

}

// продемонстрировать использование базового типа class RawDemo { public static void main(String args[]) { // создать объект класса Gen для типа Integer Gen iOb = new Gen(88); // создать объект класса Gen для типа String Gen strOb = new Gen("Generics Test"); // создать объект класса Gen для базового типа // и передать ему значение типа Double // Если аргумент типа не передается, создается базовый тип. Gen raw = new Gen(new Double(98.6)); // Здесь требуется приведение типов, так как тип неизвестен, double d = (Double) raw.getob; System.out.println("value: " + d); // Использование базового типа может привести //к исключениям при выполнении программы. // Ниже представлен ряд тому примеров. // Следующее приведение типов вызывает ошибку // при выполнении программы! // int i = (Integer) raw.getob; // Следукяцее присваивание чревато ошибкой. // Базовые типы отменяют типовую безопасность. strOb = raw; // Допустимо, но потенциально ошибочно. // String str = strOb.getob; // Ошибка при выполнении программы. // Следующее присваивание также чревато ошибкой, raw = iOb; // Допустимо, но потенциально ошибочно. // d = (Double) raw.getob; // Ошибка при выполнении программы. }

} У этой программы имеется ряд интересных особенностей. Прежде всего, базовый тип обобщенного класса Gen создается в следующем объявлении:

Gen raw = new Gen(new Double(98.6)); В данном случае аргументы типа не указываются. В итоге создается объект класса Gen, тип Т которого замещается типом Object. Базовые типы не обеспечивают типовую безопасность. Переменной базового типа может быть присвоена ссылка на любой тип объекта класса Gen. Справедливо и обратное: переменной конкретного типа из класса Gen может быть присвоена ссылка на объект класса Gen базового типа. Обе операции потенциально опасны, поскольку они действуют в обход механизма проверки типов, обязательной для обобщений. Недостаточный уровень типовой безопасности демонстрируют примеры в закомментированных строках кода в конце данной программы. Рассмотрим их по отдельности. Сначала проанализируем следующую строку кода:

Перейти на страницу:

Похожие книги