簡體   English   中英

不能投射泛型集?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM