[英]Can't cast generic sets?
我今天遇到了一個有趣的問題。 考慮以下代碼
public static class Parent {}
public static class Child extends Parent {}
Set<Child> childs = new HashSet();
Set<Parent> parents = (Set<Parent>)childs; //Error: inconvertible types
Parent parent = (Parent)new Child(); //works?!
像這樣的演員為什么不工作? 由於 generics 的各種規則,我希望隱式轉換不起作用,但為什么顯式轉換不起作用?
演員表不起作用,因為Java generics 不是 covariant 。
如果編譯器允許這樣做:
List<Child> children = new ArrayList();
List<Parent> parents = (List<Parent>)children;
那么在這種情況下會發生什么?
parents.add(new Parent());
Child c = children.get(0);
最后一行將嘗試將Parent
分配給Child
- 但Parent
不是Child
!
所有Child
都是Parent
(因為Child extends Parent
)但所有Parent
都不是Child
。
Set<Parent>
可以包含Parent
的任何子類。 Set<Child>
可以包含Child
的任何子類。 因此,一個不是Child
子類的Parent
子類將被允許在一個但不是另一個,使它們不兼容的類型。
因為一組孩子(原文如此)不是一組父母。 定義一個通用(參數化)Set 實際上與定義一個新的 class 相同,因此您定義了兩個不相交的類。
不過,超級類型的 generics 的工作方式有點不同:
Set<Child> childs = new HashSet();
Set<? extends Parent> parents = childs;
Set 是 set 和 Set 的超類型
我建議您閱讀有關 generics的文檔,以了解通用容器之間沒有 inheritance 只是因為它不是 inheritance。 Inheritance 首先意味着專業化。 想想一個設計用來容納動物的盒子,好吧,它可以由一個只包含老虎的盒子派生出來,但這意味着這個盒子當然可以為老虎做,但也可以做超級類型可以做的所有事情,包括蜜蜂所有動物的盒子。 對於人類來說,考慮這兩種分類法都有一些非常混亂的東西:hyperonimic 層次結構(專業化、繼承)和meronymic 層次結構(容器/包含)。
在你的最后一行,不需要投:
Parent parent = new Child();
斯蒂芬妮
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.