Вы назначен новый ArrayList в нетипизированный список. Ограничения общего типа не относятся к нетипизированному списку, это позволит вам помещать в него все, что вам нужно. Компилятор не отслеживает, что ваш нетипизированный список ссылается на то, что было объявлено с помощью универсального типа.
В любом случае это не вызовет ClassCastException, генерики влияют только на компиляцию. Во время выполнения
Случая, когда вы кладете тип на переменном список:
List<Integer> list = new ArrayList<Integer>();
является предпочтительным, он должен сгенерировать ошибку компиляции, сообщающую, вы кладете неправильный тип в коллекции.
Там есть описание того, как наследство, не универсальный код и общий код в this article взаимодействия:
В правильном общем коде, коллекция всегда будет сопровождаться параметром типа. Когда общий тип типа Collection используется без параметра типа, он называется сырым типом.
Первым инстинктом большинства людей является то, что коллекция действительно означает Collection<Object>
. Однако, как мы видели ранее, небезопасно передавать Collection<Part>
в месте, где требуется Collection<Object>
. Точнее сказать, что тип Collection обозначает коллекцию некоторого неизвестного типа, как и Collection<?>
.
Но подождите, это тоже не так! Рассмотрим вызов getParts()
, который возвращает коллекцию. Затем ему присваивается значение k, которое равно Collection<Part>
. Если результатом вызова является Collection<?>
, назначение будет ошибкой.
В действительности, назначение является законным, но оно генерирует непроверенное предупреждение. Предупреждение необходимо, потому что факт заключается в том, что компилятор не может гарантировать его правильность. У нас нет способа проверить устаревший код в getAssembly()
, чтобы убедиться, что действительно возвращенная коллекция представляет собой коллекцию деталей. Тип, используемый в коде, представляет собой Collection, и каждый может законно вставлять все виды объектов в такую коллекцию.
Так, разве это не ошибка? Теоретически, да; но на самом деле, если общий код будет использовать устаревший код, это должно быть разрешено. Это зависит от вас, программист, чтобы убедиться, что в этом случае назначение безопасно, потому что контракт getAssembly()
говорит, что он возвращает коллекцию частей, хотя подпись типа не показывает этого.
http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens – CupawnTae
http://stackoverflow.com/questions/2770321/what-is-a-raw -type-and-why-shouldnt-we-use-it – Reimeus
Я могу подвести итог в одном предложении: «В Java дженерики выполняются только во время компиляции». Сказав это, Java выдает вам предупреждение об использовании необработанных типов по этой причине. – Powerlord