有很長一段時間沒弄明白,Java 中 <? super T> 與 <? extends T> 的區別,看過網上不少大神的解釋,我的能力有限,好多都看到很迷糊,其中有一篇很淺顯易懂,因此記下來,分享一下:java
<? extends T>是指:上界通配符(Upper Bounds Wildcards)spa
<? super T> 是指:下界通配符(Lower Bounds Wildcards)code
1. 概述:限定泛型只能爲T類型的子類或者自己對象
2. 例子get
List<? extends Number> list2 = new ArrayList<Integer>(); List<? extends Number> list2 = new ArrayList<Double>(); List<? extends Number> list2 = new ArrayList<Number>();
3. 操做侷限性源碼
1. 概述:限定泛型只能爲T類型的父類或者自己it
2. 例子io
List<? super Integer> list1 = new ArrayList<Integer>(); List<? super Integer> list1 = new ArrayList<Number>(); List<? super Integer> list1 = new ArrayList<Object>();
3. 操做侷限性class
PESC原則泛型
生產者使用extends
若是你須要一個列表提供T類型的元素(即你想從列表中讀取T類型的元素),你須要把這個列表聲明成<? extends T>,好比List<? extends Integer>,所以你不能往該列表中添加任何元素。
消費者使用super
若是須要一個列表使用T類型的元素(即你想把T類型的元素加入到列表中),你須要把這個列表聲明成<? super T>,好比List<? super Integer>,所以你不能保證從中讀取到的元素的類型。
便是生產者,也是消費者
若是一個列表即要生產,又要消費,你不能使用泛型通配符聲明列表,好比List<Integer>。
簡單點來講就是 使用時, 須要頻繁的插入數據時, 就使用超類型限定, 須要獲取數據時,就使用子類型限定
public static <T> void copy(List<? super T> destination, List<? extends T> source) { if (destination.size() < source.size()) { throw new IndexOutOfBoundsException("destination.size() < source.size(): " + destination.size() + " < " + source.size()); } Iterator<? extends T> srcIt = source.iterator(); ListIterator<? super T> destIt = destination.listIterator(); while (srcIt.hasNext()) { try { destIt.next(); } catch (NoSuchElementException e) { // TODO: AssertionError? throw new IndexOutOfBoundsException("Source size " + source.size() + " does not fit into destination"); } // 體現點 // ** srcIt.next()... // ** destIt.set()... destIt.set(srcIt.next()); } }