[英]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>
表示可以向其添加Apple
的List
(由於Jonathan
是 Apple
,您也可以將Jonathan
放入該類型的List
中)。
它可以是List<Apple>
, List<Fruit>
或List<Object>
,但不能是List<Jonathan>
,因為您不能將任意Apple
放入List<Jonathan>
。 如您所見,在這種情況下?
可以是Apple
或其任何超類。
List<? extends Apple>
List<? extends Apple>
表示可以從中獲得Apple
的List
。 它可以是List<Apple>
或List<Jonathan>
,但不能是List<Fruit>
,因為不能保證List<Fruit>
僅包含Apple
。
這種解釋稱為“生產者- extends
,消費者- super
”規則:如果參數充當元素的消費者,則應使用super
進行聲明,反之亦然。
Jonathan
是Apple
的子類型,而不是父類型。 它會匹配<? 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)可以作為帶有通用列表參數的方法的參數發送的內容。
您可以插入的亞型Apple
到apples
,因為綁定的類型參數是一個基類,它必須引用它的所有亞型的能力。
如果Jonathan
不是Apple
的超級類型,則嘗試將Jonathan
列表發送給該方法通常是不正確的,因為允許我將Apple
插入到Jonathan
的列表中。 然后,您將擁有類型為Jonathan
引用來訪問它不了解的對象的屬性和方法,這不是類型安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.