2016-10-25 67 views
3

我正在讀一本書:Java泛型和由maurice和philip收集。混淆泛型和集合中的句子Java

有一句話我認爲這是錯誤的: 他們都給予了代碼:

​​

和的一句話是:

的古怪的短語?超級T表示所述目的地列表可以 具有任何類型的爲T的超類型的元件,正如源 列表可以具有任何類型,它是T.

AFAIK的子類型,該? super T的元件意味着目的地列表可以具有T及其子類型的元素。 我在這裏測試此:

List<? super Dog> tList = new ArrayList<>(); 
tList.add(new Dog()); 
tList.add(new HotDog()); 

其中tList.add(new Animal());是不允許的。 注意HotDog extends DogDog extends Animal

因此,如果我們根據書中聲明,它說TLIST(目標列表),是? Super Dog(? super T),可以有動物的例子,因爲它是狗的超類型(T)去

+4

它可能更清晰。它實際上意味着'dst'的泛型類型參數必須是'T'的超類型,以便它可以接受放入其中的任何子類型'T'的對象。用一句話很難解釋清楚。 – khelwood

回答

4

關於List<? super T>關於它「可能具有任何類型的T是超類型的元素」的聲明應該表示您首先必須選擇確定類型U,它是超類型T,然後聲明該列表將包含U類型的元素。這是一個非常模糊的解釋方式,所以讓我嘗試更好地構架它。

符號List<? super Dog>沒有描述一個特定的列表類型;可以更好地理解爲對特定列表類型進行匹配的模式List<Dog>List<Animal>匹配此模式,但List<HotDog>不符合。

現在,如果您查看以上內容,您會發現可以安全地將類型爲Dog的對象添加到滿足給定模式的任何列表;實際上,該模式恰好覆蓋了全部列表類型,這是安全的。此外請注意,「Dog」類型的對象自動包含所有亞型Dog,因爲這是「亞型」概念的本質。

這就是爲什麼我們使用通配符<? super T>一般描述將接受T類型的對象列表(它會起到消費者T的作用)。

相反的情況,即的<? extends Dog>,描述了所有列表類型可以作爲生產者Dog類型的對象的

所有上述規則都在PECS原則中得到了簡要概括:「生產者extends,消費者super」。