請解釋一下extends 和super 泛型限定符

https://blog.csdn.net/qq_40395278/article/details/88603655
https://www.cnblogs.com/drizzlewithwind/p/6100164.html
1、
<? extends T>限定參數類型的上界:參數類型必須是T或T的子類型
<? super T> 限定參數類型的下界:參數類型必須是T或T的超類型
2、
上界<? extends T>不能往裏存,只能往外取。即<? extends Fruit>會使往盤子裏放東西的set( )方法失效。但取東西get( )方法還有效。
因爲:<? extends T>規定了變量eList的類型只能是T的子類,當add的時候,可能會出現add(A)中A的類型是T類型父類的情況。但是get的時候可以用T類型的變量接着。

List<? extends Number> eList = null;
eList = new ArrayList<Integer>();
Number numObject = eList.get(0);  //語句1,正確
 
//Type mismatch: cannot convert from capture#3-of ? extends Number to Integer
Integer intObject = eList.get(0);  //語句2,錯誤
 
//The method add(capture#3-of ? extends Number) in the type List<capture#3-of ? extends Number> is not applicable for the arguments (Integer)
eList.add(new Integer(1));  //語句3,錯誤
語句1:List<? extends Number>eList存放Number及其子類的對象,語句1取出Number(或者Number子類)對象直接賦值給Number類型的變量是符合java規範的。 
語句2:List<? extends Number>eList存放Number及其子類的對象,語句2取出Number(或者Number子類)對象直接賦值給Integer類型(Number子類)的變量是不符合java規範的。 
語句3:List<? extends Number>eList不能夠確定實例化對象的具體類型,因此無法add具體對象至列表中,可能的實例化對象如下

下界<? super T>不影響往裏存,但往外取只能放在Object對象裏。即使用下界<? super Fruit>會使從盤子裏取東西的get( )方法部分失效,只能存放到Object對象裏。set( )方法正常。
因爲:<? super T>規定eList的類型是T類型的父類,所以get的時候不清楚到底是哪個父類,就只能用最大的父類Object類型接着。當add的時候不能addT的父類,因爲不知道eList的類型到底是什麼類型,但是可以addT和T的子類,因爲eList中的類型肯定能接住T和T的子類。

List<? super Integer> sList = null;
sList = new ArrayList<Number>();
 
//Type mismatch: cannot convert from capture#5-of ? super Integer to Number
Number numObj = sList.get(0);  //語句1,錯誤
 
//Type mismatch: cannot convert from capture#6-of ? super Integer to Integer
Integer intObj = sList.get(0);  //語句2,錯誤
 
sList.add(new Integer(1));  //語句3,正確

語句1:List<? super Integer> 無法確定sList中存放的對象的具體類型,因此sList.get獲取的值存在不確定性,子類對象的引用無法賦值給兄弟類的引用,父類對象的引用無法賦值給子類的引用,因此語句錯誤。 
語句2:同語句1。 
語句3:子類對象的引用可以賦值給父類對象的引用,因此語句正確。 
總結:下界類型通配符get方法受限,但可以往列表中添加各種數據類型的對象。因此如果你想把對象寫入一個數據結構裏,使用 ? super 通配符。限定通配符總是包括自己。

3、
上界<? extend Fruit> ,表示所有繼承Fruit的子類,但是具體是哪個子類,無法確定,所以調用add的時候,要add什麼類型,誰也不知道。但是get的時候,不管是什麼子類,不管追溯多少輩,肯定有個父類是Fruit,所以,我都可以用最大的父類Fruit接着,也就是把所有的子類向上轉型爲Fruit。

下界<? super Apple>,表示Apple的所有父類,包括Fruit,一直可以追溯到老祖宗Object 。那麼當我add的時候,我不能add Apple的父類,因爲不能確定List裏面存放的到底是哪個父類。但是我可以add Apple及其子類。因爲不管我的子類是什麼類型,它都可以向上轉型爲Apple及其所有的父類甚至轉型爲Object 。但是當我get的時候,Apple的父類這麼多,我用什麼接着呢,除了Object,其他的都接不住。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章