对于一个是List<? extends T>类型的引用list1,这实际上是某种list1引用没有指定的具体类型,它是T的一种子类,但到底是哪一种子类,编译器也无法确定,因此无法使用add()来添加对象,但是因为可以确定这个list1中的任何对象至少是T类型的,因此可以用get()来返回一个T类型的对象。
而对于一个是List<? super T>类型的引用list2,这实际上是T的一种基类,但由于不能确定到底是哪一种基类,因此list2使用get()返回来的只能是一个Object类型,原本的T类型会丢失,不过由于已经知道参数是T的某种基类,所以向其中添加T或T的子类型都是安全的,但若是向其中添加任何T的基类则会由于不确定性而报错(即使添加Object类型也不行)。
1 import java.util.*; 2 3 public class Demo_twentyeight { 4 static class Generic1<T>{ 5 private T item; 6 public void put(T item){ 7 this.item=item; 8 } 9 } 10 11 static class Generic2<T>{ 12 T item; 13 T get(){ 14 return item; 15 } 16 } 17 static <T> void f1(Generic1<? super T> generic1,T item){ 18 generic1.put(item); 19 } 20 static <T> void f2(Generic2<? extends T> generic2){ 21 generic2.get(); 22 } 23 public static void main(String[] args) { 24 Generic1<Fruit> g1=new Generic1<Fruit>(); 25 g1.put(new Apple()); 26 g1.put(new Fruit()); 27 // g1.put(new Object()); //编译无法通过 28 Generic2<Fruit> g2=new Generic2<Fruit>(); 29 Fruit f1=g2.get(); 30 } 31 32 }
更详细的解答(一位大神写的):http://zhidao.baidu.com/question/646868566975781205.html