Чтобы завершить уже очень полный ответ Джона Скита, вы должны понять концепцию стирания типа , вытекающую из необходимости совместимости с предыдущими версиями Java .
Изначально представленный на EclipseCon 2007 (больше не доступен), совместимость включала в себя следующие пункты:
- Совместимость с исходным кодом (приятно иметь ...)
- Бинарная совместимость (должна быть!)
- Совместимость миграции
- Существующие программы должны продолжать работать
- Существующие библиотеки должны иметь возможность использовать универсальные типы
- Должен иметь!
Оригинальный ответ:
Таким образом:
new ArrayList<String>() => new ArrayList()
Есть предложения для большего овефикации . Reify - «Рассматривайте абстрактное понятие как реальное», где языковые конструкции должны быть понятиями, а не просто синтаксическим сахаром.
Я должен также упомянуть checkCollection
метод Java 6, который возвращает динамически безопасное для типов представление указанной коллекции. Любая попытка вставить элемент неправильного типа приведет к немедленному ClassCastException
.
Механизм обобщений на языке обеспечивает проверку типов во время компиляции (статическую), но этот механизм можно победить с помощью непроверенных приведений .
Обычно это не проблема, поскольку компилятор выдает предупреждения обо всех таких непроверенных операциях.
Однако бывают случаи, когда одной лишь статической проверки типов недостаточно, например:
- когда коллекция передается в стороннюю библиотеку и обязательно, чтобы код библиотеки не повредил коллекцию, вставив элемент неправильного типа.
- программа завершается с ошибкой
ClassCastException
, указывая на то, что неправильно заданный элемент был помещен в параметризованную коллекцию. К сожалению, исключение может произойти в любое время после вставки ошибочного элемента, поэтому обычно оно дает мало информации или вообще не содержит информации о реальном источнике проблемы.
Обновление июль 2012, почти четыре года спустя:
Теперь (2012) подробно описано в " Правилах совместимости миграции API (проверка подписи) "
Язык программирования Java реализует обобщенные типы с использованием стирания, что гарантирует, что унаследованные и универсальные версии обычно генерируют идентичные файлы классов, за исключением некоторой вспомогательной информации о типах.
Двоичная совместимость не нарушена, поскольку можно заменить устаревший файл класса универсальным файлом класса, не изменяя и не перекомпилируя код клиента.
Для облегчения взаимодействия с неуниверсальным унаследованным кодом также можно использовать стирание параметризованного типа в качестве типа.
Такой тип называется raw type ( Спецификация языка Java 3 / 4.8 ).
Разрешение необработанного типа также обеспечивает обратную совместимость исходного кода.
В соответствии с этим следующие версии класса java.util.Iterator
являются двоичными и обратно совместимыми с исходным кодом:
Class java.util.Iterator as it is defined in Java SE version 1.4:
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
Class java.util.Iterator as it is defined in Java SE version 5.0:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}