PE,CS全稱是producer extends,consumer super的縮寫,這是 Joshua Bloch 在 Effective Java 一書 中引入的一個略顯奇怪的術語,但有助於理解泛型的用法。換言之,參數化類型表明 生產者(producer)則使用 extends, 表明消費者(consumer)則使用 superjava
簡單來講, PE 表示,若是你的方法只是想從集合獲取值,而且但願集合的類型範圍是T及其子類,那麼泛型能夠定義爲
? extends T
app
瞭解泛型的同窗應該知道 extends
是上界通配符,使用了上界通配符,只能讀取值,不能寫入值,取值的的類型是Tui
只能取值不能寫入的就是生產者,有人可能有點理解了,咱們來個更詳細的解釋,舉個栗子this
假設,咱們有個水果的對象,水果類有個addAll
方法,用來將另外一個水果集合,放入到水果對象內code
class Fruit{ private List<Fruit> fruits = new LinkedList<>(); public void addAll(List<Fruit> fruits){ for (Fruit fruit : fruits) { this.fruits.add(fruit); } } }
如今,咱們需求變了,有蘋果,香蕉分別繼承了水果這個類,若是我麼將蘋果或者香蕉集合直接放入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{ }
若是咱們要放進去怎麼辦,使用上界通配符,修改addAll
方法,使用了上界通配符後,元素只能讀,不能寫,傳入的集合類型範圍是Fruit或者其子類集合繼承
public void addAll(List<? extends Fruit> f){ for (Fruit fruit : f) { this.fruits.add(fruit); }
有人會問了,這個上界通配符,跟PE有什麼關係? 固然有,PE是producer extends
的縮寫,咱們仔細看看,對於addAll
方法來講,只是要消費入參,那麼入參就是生產者,說着這,估計不少人已經明白了it
PE是針對方法來講的,若是某個方法的入參,須要一個生產者,而且範圍是泛型的子類,那麼使用上界通配符extends編譯
簡單來講, CS 表示,若是你的方法只是想往集合寫入值,而且集合的類型範圍但願是T及其父類,那麼泛型能夠定義爲
? super T
來表示class
瞭解泛型的同窗應該知道,super
表示下界通配符,使用了下界通配符,只能寫入值,不能取值,寫入的值必須是T或者其子類
只能寫入,不能取出就是消費者,有人可能有點理解了,咱們來個更詳細的解釋,舉個例子
咱們仍是沿用上面的例子,咱們進行改造一下,蘋果類有個addAll
方法,傳入一個蘋果集合,將蘋果對象放入這個集合裏面
public class Apple extends Fruit{ private Apple apple = new Apple(); public void addAll(List<Apple> apples){ apples.add(apple); } }
如今需求變了,咱們變動,咱們想傳入一個更大的水果集合,將蘋果添加入水果集合裏面,畢竟蘋果是屬於水果的子類,咱們直接將水果集合傳入進去,會編譯報錯,咱們改造一下addAll
方法,使用下界通配符將它的接收範圍擴大,傳入的集合範圍是Apple或者其父類集合
public void addAll(List<? super Apple> apples){ apples.add(apple); }
有人會問了,這個下界通配符,跟CS有什麼關係? 固然有,CS是consumer super
的縮寫,對於addAll
方法來講,只要是將東西放進到入參內,那麼入參就是消費者
CS也是針對方法來講的,若是某個方法的入參須要消費方法內的東西,入參而且是泛型的父類,那麼使用下界通配符super
若是進行簡單的概括,那就是