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

泛型關鍵字說明

  • <? 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);

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

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