簡體   English   中英

為什么在使用“擴展”時需要泛型泛型?

[英]Why need cast generics when use 'extends'?

為什么在使用T extends A時需要強制轉換為List<T>

class A{}
public <T extends A> List<T> someMethod() {
    List<A> list = new ArrayList<>();
    List<T> result1 = list; // !! Does not compile, why?
    List<T> result2 = (List<T>) list; // ok, but why need cast?

    return  result2;
}

閱讀有關“通配符和子類型”的文檔 :在您的示例中, List<T>List<A>的子類型。 您不能將實例分配給其子類型的變量。

想象一個更簡單的情況: NumberInteger

Number n = ...;
Integer i;
i = n;  // error
i = (Integer) n;

您可以拋棄編譯錯誤,並且只要知道變量發生了什么就可以正常工作。 如果nDouble ,則將得到ClassCastException


使用示例中的集合,強制轉換將始終有效,因為在運行時不檢查泛型類型信息,即,它只是從List強制轉換為List

但是,當您擁有List類的通用類型時,還有另一種復雜度:使用通用類型,您可以保證該列表所包含的內容(將其視為對自己,使用代碼的開發人員和編譯器的承諾)。 通過分配“更廣泛”的列表,以后使用時可能會遇到麻煩。

class Apple extends Fruit
class Orange extends Fruit

List<Fruit> fruitBasket = Arrays.asList(new Orange(), new Apple());
List<Apple> applesOnly;
applesOnly = (List<Apple>) fruitBasket;

for (Apple apple : applesOnly) // ClassCastException because of the Orange in fruitBasket

在此示例中,您通過分配fruitBasket違反了applesOnly僅包含蘋果的承諾。 這就是為什么大多數IDE在投射泛型時都會給您至少一個警告的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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