为什么我不能将集合分配给彼此?

why can't I assign collections to each other?

我有继承层次Shape->Rectangle->Square

并且我有带参数 T 的 ShapeCollection class 来放置任何形状 class 类型:Shape、Rectangle、Square。 但我不明白,为什么这是有效的:

List<Rectangle> rectangleList = new ArrayList<>();
List<? extends Shape> shapeList = rectangleList;

但是这是行不通的

List<ShapeCollection<Rectangle>> recCallList = new ArrayList<>();
List<ShapeCollection<? extends Shape>> shapeCallList = recCallList;

我假设 ShapeCollection 声明为 class ShapeCollection<T extends Shape> {}.

这与 subtyping and wildcards 在 Java 中的工作方式有关。想象一下 Java 允许你做你想做的事:

List<ShapeCollection<Rectangle>> recCallList = new ArrayList<>();
List<ShapeCollection<? extends Shape>> shapeCallList = recCallList;  // imagine it's ok

ShapeCollection<Square> squareCollection = ...;
shapeCallList.add(squareCollection); // uh-oh, mix of Square and Rectangle

现在你可以在 recCallList 中添加一个 ShapeCollection<Square>,这是不好的。您可以对 List<ShapeCollection<? extends Shape>> 执行 ShapeCollection<Square> 的原因是 ShapeCollection<Square>ShapeCollection<? extends Shape> 的子类,如从 Oracle 文档中获取的这张图片所示:

Java 泛型是不变的,这意味着 List<S>List<T> 是不相关的类型,即使 ST.[=24 的子类型=]

在您的情况下,这意味着 List<ShapeCollection<Rectangle>>List<ShapeCollection<? extends Shape>> 无关,即使 ShapeCollection<Rectangle>ShapeCollection<? extends Shape>> 的子类型。

如果需要差异,则必须使用有界通配符进行声明。也就是说,List<Rectangle>List<Circle> 的公共超类型是 List<? extends Shape>。同样,List<ShapeCollection<Rectangle>>List<ShapeCollection<Circle>> 的公共超类型是 List<? extends ShapeCollection<? extends Shape>>.