簡體   English   中英

為什么不允許這種對通用和通配符的使用?

[英]Why is this such use of generic and wildcard not allowed?

這段代碼

static void writeTo(List<? super Apple> apples) {
        apples.add(new Apple());
        apples.add(new Jonathan());
    }

該代碼的作者指出

參數apples是某種類型的List,它是Apple的基本類型。 因此,您知道添加Apple或Apple的子類型是安全的。 由於下限是蘋果,

喬納森(Jonathan)是Apple的子類。

但是當我嘗試這個

    List<Jonathan> loj = new ArrayList<Jonathan>();
    listSuper(loj);

它給了我這個錯誤

The method listSuper(List<? super Apple>) in the type Basket<T> is not applicable for the arguments (List<Jonathan>)

listSuper看起來像這樣

static void listSuper (List<? super Apple> cont) {}

兩者有何不同?

另外,我想到的第一個代碼使我感到困惑嗎? 超級T表示T的任何基本類型,但是從外觀上他添加了T的一個亞型。我很困惑。

List<? super Apple> List<? super Apple>表示可以向其添加AppleList (由於Jonathan Apple ,您也可以將Jonathan放入該類型的List中)。

它可以是List<Apple>List<Fruit>List<Object> ,但不能是List<Jonathan> ,因為您不能將任意Apple放入List<Jonathan> 如您所見,在這種情況下? 可以是Apple或其任何超類。

List<? extends Apple> List<? extends Apple>表示可以從中獲得AppleList 它可以是List<Apple>List<Jonathan> ,但不能是List<Fruit> ,因為不能保證List<Fruit>僅包含Apple

這種解釋稱為“生產者- extends ,消費者- super ”規則:如果參數充當元素的消費者,則應使用super進行聲明,反之亦然。

JonathanApple的子類型,而不是父類型。 它會匹配<? extends Apple> <? extends Apple>但不匹配<? super Apple> <? super Apple>

代碼的作者是錯誤的。 您不能將Apple的子類傳遞給采用?的方法。 超級蘋果,只有蘋果本身和蘋果的超類。 如果您希望能夠添加Apple的子類,則需要使用? 擴展了蘋果。

類型參數必須是Apple的超類型 ,而不是Jonathan子類 因此,例如,這將是有效的:

List<Fruit> loj = new ArrayList<Fruit>();     
listSuper(loj); 

兩者有何不同?

另外,我想到的第一個代碼使我感到困惑嗎? 超級T表示T的任何基本類型,但是從外觀上他添加了T的一個亞型。我很困惑。

您必須區分(1)可以插入通用列表的內容和(2)可以作為帶有通用列表參數的方法的參數發送的內容。

  1. 您可以插入的亞型Appleapples ,因為綁定的類型參數是一個基類,它必須引用它的所有亞型的能力。

  2. 如果Jonathan不是Apple的超級類型,則嘗試將Jonathan列表發送給該方法通常是不正確的,因為允許我將Apple插入到Jonathan的列表中。 然后,您將擁有類型為Jonathan引用來訪問它不了解的對象的屬性和方法,這不是類型安全的。

暫無
暫無

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

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