Java无法将原始通用类型列表转换为通配符通用类型列表

时间:2018-09-26 17:53:06

标签: java generics raw-types

这里有一个快速的通用类,使这个问题更容易理解。您可以根据需要假装它“装箱”一个值。

public class Box<T> {    }

问题

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

Box b1 = new Box<>();
Box<?> b2 = b1;
Box b3 = b2;

因此,我很清楚,可以将使用通配符参数化的原始BoxBox都转换为彼此的类型。

Object box = (Box<?>)(Box) (Box<?>)(Box) ... new Box<>();// Valid (without the ellipsis)

那么为什么,我的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>

“无法从List<Box>投射到List<Box<?>>”,反之亦然...


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

我猜想有人会尝试提出List<Dog>无法转换为List<Animal>的事实,反之亦然。但是,这样做的原因是:

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

Dog dog = ((List<Dog>) animals).get(0);

Dog的列表不是不是Animal的列表,因为它只能包含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);

最后

This出现了,这告诉我,如果Java允许的话,这样的强制转换是安全的。我想知道的是为什么不允许从List<Box>List<Box<?>>的投射,以及如何从{{ 1}}。

如果还有一个问题可以完全回答这两个问题,请将其标记为重复。我自己搜索答案时不知道要查找什么。

0 个答案:

没有答案