为什么我不能将集合分配给彼此?
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>
是不相关的类型,即使 S
是 T
.[=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>>
.
我有继承层次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>
是不相关的类型,即使 S
是 T
.[=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>>
.