简体   繁体   English

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

[英]why can't I assign collections to each other?

I have inheritance hierarchy Shape->Rectangle->Square我有 inheritance 层次结构形状->矩形->正方形

And I have ShapeCollection class with parameter T to put there any of shape class type: Shape, Rectangle, Square.我有带有参数 T 的 ShapeCollection class 可以放置任何形状 class 类型:形状、矩形、正方形。 But I don't understand, why this is work:但我不明白,为什么这是工作:

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

But this is doesn't work但这是行不通的

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

Java Generics are invariant, meaning that List<S> and List<T> are unrelated types even if S is a subtype of T . Java Generics 是不变的,这意味着即使ST的子类型, List<S>List<T>也是不相关的类型。

In your case, this means that List<ShapeCollection<Rectangle>> is unrelated to List<ShapeCollection<? extends Shape>>在您的情况下,这意味着List<ShapeCollection<Rectangle>>List<ShapeCollection<? extends Shape>> List<ShapeCollection<? extends Shape>> even though ShapeCollection<Rectangle> is a subtype of ShapeCollection<? extends Shape>> List<ShapeCollection<? extends Shape>>即使ShapeCollection<Rectangle>ShapeCollection<? extends Shape>> ShapeCollection<? extends Shape>> . ShapeCollection<? extends Shape>>

If you want variance, you must declare that by using a bounded wildcard.如果您想要方差,则必须使用有界通配符声明它。 That is, the common supertype of List<Rectangle> and List<Circle> is List<? extends Shape>也就是说, List<Rectangle>List<Circle>的共同超类型是List<? extends Shape> List<? extends Shape> . List<? extends Shape> Likewise, the common supertype of List<ShapeCollection<Rectangle>> and List<ShapeCollection<Circle>> is List<? extends ShapeCollection<? extends Shape>>同样, List<ShapeCollection<Rectangle>>List<ShapeCollection<Circle>>的共同超类型是List<? extends ShapeCollection<? extends Shape>> List<? extends ShapeCollection<? extends Shape>> List<? extends ShapeCollection<? extends Shape>> . List<? extends ShapeCollection<? extends Shape>>

I assume ShapeCollection is declared with something like class ShapeCollection<T extends Shape> {} .我假设ShapeCollection是用class ShapeCollection<T extends Shape> {}类的东西声明的。

This is has to do with how subtyping and wildcards works in Java.这与子类型和通配符在 Java 中的工作方式有关。 Imagine that Java allowed you to do what you want:想象一下 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

Now you can add a ShapeCollection<Square> to recCallList , which is bad.现在您可以将ShapeCollection<Square>添加到recCallList ,这很糟糕。 The reason you can do a ShapeCollection<Square> to a List<ShapeCollection<? extends Shape>>您可以对List<ShapeCollection<? extends Shape>>执行ShapeCollection<Square>的原因List<ShapeCollection<? extends Shape>> is that ShapeCollection<Square> is a subclass of ShapeCollection<? extends Shape> List<ShapeCollection<? extends Shape>>ShapeCollection<Square>ShapeCollection<? extends Shape> ShapeCollection<? extends Shape> , as illustrated in this picture taken from Oracle docs: ShapeCollection<? extends Shape> ,如这张取自 Oracle 文档的图片所示:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM