无法投射通用套装?
我今天遇到了一个有趣的问题。 请考虑以下代码
public static class Parent {} public static class Child extends Parent {} Set childs = new HashSet(); Set parents = (Set)childs; //Error: inconvertible types Parent parent = (Parent)new Child(); //works?!
为什么这样的演员不会工作? 我希望由于generics的各种规则,隐式转换不起作用,但为什么不能显式转换?
演员表不起作用,因为Javagenerics不是协变的 。
如果编译器允许这样:
List children = new ArrayList(); List parents = (List )children;
那么在这种情况下会发生什么?
parents.add(new Parent()); Child c = children.get(0);
最后一行将尝试将Parent
分配给Child
– 但Parent
不是Child
!
所有Child
都是Parent
(因为Child extends Parent
),但所有Parent
都不是Child
。
Set
可以包含Parent
任何子类。 Set
可以包含Child
任何子类。 因此,不是子类的Child
类的Parent
的子类将被允许在一个而不是另一个子类中,从而使它们成为不兼容的类型。
因为一组孩子(原文如此)不是一组父母。 定义generics(参数化)集实际上与定义新类相同,因此您定义了两个不相交的类。
虽然,超类型的generics工作方式有点不同:
Set childs = new HashSet(); Set extends Parent> parents = childs;
Set是set和Set的超类型
我建议你阅读这篇关于generics的文档,以了解generics容器之间没有inheritance,因为它不是inheritance。 毕竟,inheritance意味着专业化。 想象一个用于容纳动物的盒子,好吧它可以通过一个只包含老虎的盒子来获得但是它意味着盒子可以为老虎做的,当然,也可以做超级类型可以做的所有事情,包括做好事所有动物的盒子。 对于人类来说,考虑两种类型的分类法有一些非常混乱的东西:超级层次结构(特化,inheritance)和meronymic层次结构(容器/包含)。
在你的最后一行中,不需要同时投射:
Parent parent = new Child();
斯特凡