泛型關鍵字說明
- <? extends T>:是指 “上界通配符” ?>=T
- <? super T>:是指 ”下界通配符“ ?<=T
類型結構圖
在類中 extends 與 super對比
- ?所代表得類,是Meat得父類 即?>=Meat ,本例中?這裡可以代表為Meat,Food這兩種類型
補充: 出錯的兩句的?這裡,泛型要求傳入Meat,Food類型,但是傳入的确實Chicken,Pock,是以出錯。
//隻能放meat以及meat得父類 ?>=Meat
Plate<? super Meat> plate21 = new Plate<>(new Meat());
Plate<? super Meat> plate22 = new Plate<>(new Food());
//存放meat得子類chicken以及pock就會報錯
//Plate<? super Meat> plate23 = new Plate<>(new Chicken()); //會出錯
//Plate<? super Meat> plate24 = new Plate<>(new Pock());//會出錯
- ?所代表得類,是Meat得子類 即?<=Meat ,本例中的?可以代表為Meat,Chicken,Pock這三種類型
補充:出錯的這句的?這裡,泛型要求傳入Meat,Food類型,但是傳入的确實Chicken,Pock,是以出錯。
//隻能存放meat以及meat得子類 ?<=Meat
Plate<? extends Meat> plate31 = new Plate<>(new Meat());
Plate<? extends Meat> plate32 = new Plate<>(new Chicken());
Plate<? extends Meat> plate33 = new Plate<>(new Pock());
//存放meate得父類food就會報錯
//Plate<? extends Meat> plate34 = new Plate<>(new Food());//會報錯
在List中extends與super對比
- ?所代表得類,是Meat得父類 即?>=Meat ,本例中?這裡可以代表為Meat,Food這兩種類型
補充:出錯的兩句的?這裡,泛型要求傳入Meat,Food類型,但是傳入的确實Chicken,Pock,是以出錯。
List<? super Meat> list21 = new ArrayList<Food>();
List<? super Meat> list22 = new ArrayList<Meat>();
//List<? super Meat> list23 = new ArrayList<Chicken>(); //會出錯
//List<? super Meat> list24 = new ArrayList<Pock>(); //會出錯
- ?所代表得類,是Meat得子類 即?<=Meat ,本例中的?可以代表為Meat,Chicken,Pock這三種類型
補充:出錯的這句的?這裡,泛型要求傳入Meat,Food類型,但是傳入的确實Chicken,Pock,是以出錯。
//隻能存放meat以及meat得子類 <=
List<? extends Meat> list31 = new ArrayList<Meat>();
List<? extends Meat> list32 = new ArrayList<Chicken>();
List<? extends Meat> list33 = new ArrayList<Pock>();
//存放meate得父類food就會報錯
//List<? extends Meat> list34 = new ArrayList<Food>();//會報錯
在List中的add方法,extends與super對比
- ?所代表得類,是Meat得父類 即?>=Meat ,本例中?這裡可以代表為Meat,Food這兩種類型
補充:看到這裡就會很奇怪,為啥list21.add(new Food())會報錯
原因:這裡?>=Meat,我們取最小值那就是Meat,就将?換成Meat,就能明白了(具體可以通過下面ArrayList源碼分析)
List<? super Meat> list21 = new ArrayList<>();
//list存放meat以及meat得子類 <=
list21.add(new Meat());
list21.add(new Chicken());
list21.add(new Pock());
//list不能存放meat得父類
//list21.add(new Food());//會報錯
- ?所代表得類,是Meat得子類 即?<=Meat ,本例中的?可以代表為Meat,Chicken,Pock這三種類型
補充:看到這裡就會很奇怪,為啥都報錯
原因:這裡?<=Meat,我們取最小值并不知道是哪一個,是以就沒有辦法添加資料了(具體可以通過下面ArrayList源碼分析)
List<? extends Meat> list31 = new ArrayList<>();
//list31.add(new Meat());//會報錯
//list31.add(new Food());//會報錯
//list31.add(new Chicken());//會報錯
//list31.add(new Pock());//會報錯
我們通過ArrayList中的add源碼來分析這個問題,這裡添加的 E 是一個泛型,是以
- 在使用List<? super Meat>(?>=Meat ) 建立ArrayList時候,它并不知道你會傳入會是Meat還是Food,就會出現兩種可能List<Meat> list21 ;List<Food> list21;為了相容兩者可能,是以,此時的List<? super Meat>就必須同時滿足Meat和Food的可能,也就相當于List<? super Meat>,是以添加的list21.add(new Food())//會報錯
- 在使用List<? extends Meat>(?<=Meat )建立ArrayList時候,它并不知道你會傳入會是Meat,Chicken還是Pock,就會出現兩種可能List<Meat> list31 ; List<Chicken> list31 ;List<Pock> list31 ;為了相容三者可能,是以,此時的List<? super Meat>中的?就必須同時滿足Meat,Chicken還是Pock三者的可能,是以添加的四個都會報錯
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
在List中的get方法,extends與super對比
- ?所代表得類,是Meat得父類 即?>=Meat ,所有的對象的父類都是Object,是以這裡也就能了解
List<? super Meat> list21 = new ArrayList<Food>();
Object object21 = list21.get(0);
- ?所代表得類,是Meat得子類 即?<=Meat ,是以這裡所有對象,都會是Meat的子類
List<? extends Meat> list31 = new ArrayList<>();
Meat meat = list31.get(0);
這裡得到添加進去的方法,因為可以強制轉換,是以就不在累贅了