關於Java泛型,這里我不想總結它是什么,這個百度一下一大堆解釋,各種java的書籍中也有明確的定義,只要稍微看一下就能很快清楚.從泛型的英文名字Generic type也能看出,Generic普通、一般、通用的,是一個概括性的詞,那么泛型從名字上也就好理解了,它是一種通用類型,是java中各種類型的概括.
?是java泛型中的通配符,它代表java中的某一個類,那么<? extends T>就代表類型T的某個子類,<? super T>就代表類型T的某個父類.
這里我們先定義一組有繼承關系的類:
//子類-->父類 小紅蘋果--紅蘋果--蘋果--水果--好吃的--吃的
這些類都是左側的類為與它相連接的右側的類的子類.
那么<? extends 蘋果> 代表的是左側藍字和綠字的類中的某個類,而<? super 蘋果>代表的就是綠字和紅字的類中的某個類.
這里要注意的是<? extends T>或是<? super T>代表的是范圍內的某個特定的類,而不是范圍內的所有類.
//所以只要在范圍內,我們可以如下這樣的隨意賦值 List<? extends 蘋果> list1 = new ArrayList<蘋果>(); List<? extends 蘋果> list2= new ArrayList<紅蘋果>(); List<? extends 蘋果> list3 = new ArrayList<小紅蘋果>();
但是對於List<? extends 蘋果> list來說,代表的是一個范圍內的某個類,但是卻不確定是哪個類,所以如果我們向這個list中添加元素的時候:
List<? extends 蘋果> list = new ArrayList<蘋果>(); list.add(蘋果); //編譯錯誤 list.add(紅蘋果); //編譯錯誤 list.add(小紅蘋果); //編譯錯誤
因為編譯器並不知道list到底是哪個類(只有在運行的時候才能確定指代的哪個類),如果list是紅蘋果,那么list.add(蘋果)就將一個父類賦值給子類了,是錯誤的.顯然如果向這個list中添加類,都不能保證是正確的.可能會說小紅蘋果沒有子類,添加小紅蘋果不會錯,但是這只是我定義的一個繼承圖中是這樣,我們完全可以繼續定義個小小紅蘋果來繼承小紅蘋果,這個繼承是沒有下限的.這個反推出一個結論<? extends T>是一個有上限T的類型.那么我們馬上就發現<? super T>實際上是有下限T的類型.
因為對於<? extends T>有上限T,故我們如果list.get(0)一定返回的是T或是T的子類,這個是確定的,得出:
List<? extends 蘋果> list1 = new ArrayList<蘋果>(); 蘋果 a = list1.get(0); //這個是一定成立的,編譯也不會有問題
List<? extends 蘋果> list2 = new ArrayList<紅蘋果>();
蘋果 a = list2.get(0);
List<? extends 蘋果> list3 = new ArrayList<小紅蘋果>();
蘋果 a = list3.get(0);
然后我們來看<? super T>,因為它有下限,故我們可以馬上得出,如果向其中添加T類型的對象是沒問題的.因為<? super T>是T的某個父類,將子類T賦值給父類沒任何問題:
List<? super 蘋果> list = new ArrayList<蘋果>(); list.add(蘋果); //無任何問題 List<? super 蘋果> list = new ArrayList<水果>(); list.add(蘋果); //無任何問題