天天看點

【android學習】泛型通配符extends與super差別

泛型關鍵字說明

  • <? extends T>:是指 “上界通配符”  ?>=T
  • <? super T>:是指 ”下界通配符“  ?<=T

類型結構圖

【android學習】泛型通配符extends與super差別

在類中 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);
           

這裡得到添加進去的方法,因為可以強制轉換,是以就不在累贅了