[英]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 是不变的,这意味着即使S
是T
的子类型, 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.