您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java泛型的PE和CS原則說明”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java泛型的PE和CS原則說明”吧!
PE,CS全稱是producer extends,consumer super的縮寫,這是 Joshua Bloch 在 Effective Java 一書 中引入的一個略顯奇怪的術(shù)語,但有助于理解泛型的用法。換言之,參數(shù)化類型代表 生產(chǎn)者(producer)則使用 extends, 代表消費(fèi)者(consumer)則使用 super
簡單來說, PE 表示,如果你的方法只是想從集合獲取值,并且希望集合的類型范圍是T及其子類,那么泛型可以定義為
? extends T
了解泛型的同學(xué)應(yīng)該知道 extends
是上界通配符,使用了上界通配符,只能讀取值,不能寫入值,取值的的類型是T
只能取值不能寫入的就是生產(chǎn)者,有人可能有點(diǎn)理解了,我們來個更詳細(xì)的解釋,舉個栗子
假設(shè),我們有個水果的對象,水果類有個addAll
方法,用來將另一個水果集合,放入到水果對象內(nèi)
class Fruit{ private List<Fruit> fruits = new LinkedList<>(); public void addAll(List<Fruit> fruits){ for (Fruit fruit : fruits) { this.fruits.add(fruit); } } }
現(xiàn)在,我們需求變了,有蘋果,香蕉分別繼承了水果這個類,如果我么將蘋果或者香蕉集合直接放入addAll
方法,會編譯報錯,因為蘋果集合,不是水果集合
public static void main(String[] args){ List<Apple> appleList = new LinkedList<>(); Fruit fruit = new Fruit(); // 編譯報錯 fruit.addAll(appleList); } class Apple extends Fruit{ } class Banana extends Fruit{ }
如果我們要放進(jìn)去怎么辦,使用上界通配符,修改addAll
方法,使用了上界通配符后,元素只能讀,不能寫,傳入的集合類型范圍是Fruit或者其子類集合
public void addAll(List<? extends Fruit> f){ for (Fruit fruit : f) { this.fruits.add(fruit); }
有人會問了,這個上界通配符,跟PE有什么關(guān)系? 當(dāng)然有,PE是producer extends
的縮寫,我們仔細(xì)看看,對于addAll
方法來說,只是要消費(fèi)入?yún)?那么入?yún)⒕褪?strong>生產(chǎn)者,說著這,估計很多人已經(jīng)明白了
PE是針對方法來說的,如果某個方法的入?yún)?需要一個生產(chǎn)者,并且范圍是泛型的子類,那么使用上界通配符extends
簡單來說, CS 表示,如果你的方法只是想往集合寫入值,并且集合的類型范圍希望是T及其父類,那么泛型可以定義為
? super T
來表示
了解泛型的同學(xué)應(yīng)該知道,super
表示下界通配符,使用了下界通配符,只能寫入值,不能取值,寫入的值必須是T或者其子類
只能寫入,不能取出就是消費(fèi)者,有人可能有點(diǎn)理解了,我們來個更詳細(xì)的解釋,舉個例子
我們還是沿用上面的例子,我們進(jìn)行改造一下,蘋果類有個addAll
方法,傳入一個蘋果集合,將蘋果對象放入這個集合里面
public class Apple extends Fruit{ private Apple apple = new Apple(); public void addAll(List<Apple> apples){ apples.add(apple); } }
現(xiàn)在需求變了,我們變更,我們想傳入一個更大的水果集合,將蘋果添加入水果集合里面,畢竟蘋果是屬于水果的子類,我們直接將水果集合傳入進(jìn)去,會編譯報錯,我們改造一下addAll
方法,使用下界通配符將它的接收范圍擴(kuò)大,傳入的集合范圍是Apple或者其父類集合
public void addAll(List<? super Apple> apples){ apples.add(apple); }
有人會問了,這個下界通配符,跟CS有什么關(guān)系? 當(dāng)然有,CS是consumer super
的縮寫,對于addAll
方法來說,只要是將東西放進(jìn)到入?yún)?nèi),那么入?yún)⒕褪?strong>消費(fèi)者
CS也是針對方法來說的,如果某個方法的入?yún)⑿枰M(fèi)方法內(nèi)的東西,入?yún)⒉⑶沂欠盒偷母割?那么使用下界通配符super
如果進(jìn)行簡單的歸納,那就是
只從方法入?yún)⒓汐@取值,那么使用 extends
只從方法入?yún)⒓蠈懭胫?那么使用 super
感謝各位的閱讀,以上就是“Java泛型的PE和CS原則說明”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java泛型的PE和CS原則說明這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。