«Неуниверсальная» версия универсального типа называется «необработанным типом».
Передача универсального типа, в котором запрашивается необработанный эквивалент, обычно в порядке. На самом деле это основная причина, по которой дженерики в Java работают так, как они (с стиранием): для обеспечения взаимодействия между «обобщенным» кодом и кодом предварительного дженерика.
Главное, с чем вам следует быть осторожным, это то, что если вы передадите List<Foo>
чему-то, что запрашивает List
, они могут поместить не Foo
объекты в List
. Вы не получите никакой проверки времени компиляции, чтобы помочь вам здесь. Вы делаете некоторые проверки во время выполнения: ClassCastException
будет выброшено, когда вы используете метод, который возвращает Foo
на вашем List<Foo>
, и он должен вернуть не Foo
.
Если вам нужно более быстрое поведение при сбое, вы можете обернуть List<Foo>
в Collections.checkedList()
, чтобы получить список, который будет проверять тип элементов при вставке.
Все становится сложнее, если Foo
сам по себе является универсальным типом. Проверки во время выполнения выполняются только для типов reified (то есть: для типа с удаленными параметрами универсального типа), поэтому, если вы дадите им List<Set<Bar>>
и они вставят Set<Baz>
или просто Set
, вы не узнаете, так как во время выполнения / reified тип элемента Set
в любом случае.