Java无法从原始泛型类型列表转换为通配符泛型类型列表

Krö*_*röw 5 java generics raw-types

这是一个快速的小通用类,使这个问题更容易理解.如果你愿意,你可以假装它"装箱"一个值.

public class Box<T> {    }
Run Code Online (Sandbox Code Playgroud)

现在,在我的main方法中,我可以这样:

Box b1 = new Box<>();
Box<?> b2 = b1;
Box b3 = b2;
Run Code Online (Sandbox Code Playgroud)

所以我很清楚,带有通配符的raw BoxBox参数化都可以同时传递给彼此的类型.

Object box = (Box<?>)(Box) (Box<?>)(Box) ... new Box<>();// Valid (without the ellipsis)
Run Code Online (Sandbox Code Playgroud)

那么为什么List的原始盒子不能被转换成List通配符盒,反之亦然?(如果你能找到它,那么任何负责编译错误的文档都会出现以下代码.)

List<Box> rawBoxes = new LinkedList<>();
List<Box<?>> wildcardBoxes = new LinkedList<>();

Object o1 = (List<Box<?>>) rawBoxes;// Cannot cast from List<Box> to List<Box<?>>
Object o2 = (List<Box>) wildcardBoxes;// Cannot cast from List<Box<?>> to List<Box>
Run Code Online (Sandbox Code Playgroud)

"不能施放List<Box>List<Box<?>>",反之亦然......


在你回答/标记为欺骗之前......

我猜想有人会尝试提出一个事实,即List<Dog>不能将其转换为a List<Animal>,反之亦然.然而,原因是:

List<Animal> animals = new LinkedList<>();
animals.add(new Cat());

Dog dog = ((List<Dog>) animals).get(0);
Run Code Online (Sandbox Code Playgroud)

列表Dogs是不是列表AnimalS,因为它只能容纳Dog秒.

有了List<Box>List<Box<?>>,任何一种Box都可以放入:

List<Box> rawBoxes = new LinkedList<>();
List<Box<?>> wildcardBoxes = new LinkedList<>();

Box rawBox = new Box<>();
Box<?> wildcardBox = new Box<>();
Box<String> stringBox = new Box<>();

// They can both take raw boxes
rawBoxes.add(rawBox);
wildcardBoxes.add(rawBox);

// They can both take wildcard boxes
rawBoxes.add(wildcardBox);
wildcardBoxes.add(wildcardBox);

// They can both take boxes storing arbitrary stuff
rawBoxes.add(stringBox);
wildcardBoxes.add(stringBox);
Run Code Online (Sandbox Code Playgroud)

最后

出现了,它告诉我,如果Java允许这样的演员阵容是安全的.我想知道的是,为什么从铸造List<Box>List<Box<?>>不允许如何获取List<Box<?>>的关闭List<Box>.

如果还有另一个问题将彻底回答这两件事,请将此标记为重复.在我自己寻找答案时,我不确切地知道要查找什么.