Безопасно ли отличать от List <Optional> to List <Optional <? >>?

Если у вас есть необработанный тип на Java, вы можете смело назначить/применить его к тому же типу с неограниченным подстановочным знаком. Например, List можно безопасно отнести к List<?>, который удаляет его необработанную природу и позволяет использовать его в безопасном (с типом) способом 1.

С другой стороны, Java не позволяет выставлять из самого List с параметром raw, например List<Optional>, в список одного и того же типа с неограниченным шаблоном, например List<Optional<?>>.

Вы все еще можете сделать это, сбросив весь исходный List и снова выполнить резервное копирование (неявно через назначение):

List<Optional> rawOptionalList = null;
List<Optional<?>> wildcardOptionalList = (List)rawOptionalList;

Конечно, это вызывает предупреждение о непроверенном преобразовании (от List до List<Optional<?>>).

Мне кажется, что это преобразование гарантировано безопасно: не List<Optional<?>> так же безопасно, как List<Optional> таким же образом, что безопасное литиевание Optional в Optional<?>?


1... но вы никогда не сможете добавить что-либо в этот список, поскольку ничто не будет соответствовать захвату ? для метода add(?). Это цена, которую вы платите за безопасность.

Ответ 1

Да, это безопасно. Общая проверка выполняется только во время компиляции.

Ответ 2

Тип erasure в Java означает, что все параметризованные типы стираются во время выполнения. В вашем случае a List<Optional> - это всего лишь List во время выполнения, а Optional<MyClass> - это всего лишь Optional во время выполнения.

Когда вы получаете содержащийся класс из List или Optional, Java делает приведение к параметризованному типу. Таким образом, ваш код не только безопасен, это именно то, что делает компилятор Java.