Java泛型中 extends和super

Java泛型中的extends和super理解

 


在平時看源碼的時候我們經常看到泛型,且經常會看到extends和super的使用,看過其他的文章裏也有講到上界通配符和下屆通配符,總感覺講的不夠明白。這裏備註一下,以免忘記。

extends也稱爲上界通配符,就是指定上邊界。即泛型中的類必須爲當前類的子類或當前類。
super也稱爲下屆通配符,就是指定下邊界。即泛型中的類必須爲當前類或者其父類。
這兩點不難理解,extends修飾的只能取,不能放,這是爲什麼呢?

先看一個列子:

public class Food {}
public class Fruit extends Food {}
public class Apple extends Fruit {}
public class Banana extends Fruit{}

public class GenericTest {

public void testExtends(List<? extends Fruit> list){

//報錯,extends爲上界通配符,只能取值,不能放.
//因爲Fruit的子類不只有Apple還有Banana,這裏不能確定具體的泛型到底是Apple還是Banana,所以放入任何一種類型都會報錯
//list.add(new Apple());

//可以正常獲取
Fruit fruit = list.get(1);
}

public void testSuper(List<? super Fruit> list){

//super爲下界通配符,可以存放元素,但是也只能存放當前類或者子類的實例,以當前的例子來講,
//無法確定Fruit的父類是否只有Food一個(Object是超級父類)
//因此放入Food的實例編譯不通過
list.add(new Apple());
// list.add(new Food());

Object object = list.get(1);
}

在testExtends方法中,因爲泛型中用的是extends,在向list中存放元素的時候,我們並不能確定List中的元素的具體類型,即可能是Apple也可能是Banana。因此調用add方法時,不論傳入new Apple()還是new Banana(),都會出現編譯錯誤。

理解了extends之後,再看super就很容易理解了,即我們不能確定testSuper方法的參數中的泛型是Fruit的哪個父類,因此在調用get方法時只能返回Object類型。結合extends可見,在獲取泛型元素時,使用extends獲取到的是泛型中的上邊界的類型(本例子中爲Fruit),範圍更小。

總結:
在使用泛型時,存取元素時用super,獲取元素時,用extends
————————————————

package com.Iori;

import android.app.Activity;

import com.Iori.Util.CommUtil;

import java.lang.ref.WeakReference;

import com.Iori.IEntity;
import androidx.annotation.Nullable;

public abstract class CommonCallback<T extends IEntity> extends GeneralCallback<T>
{
    protected Activity __this;
    public CommonCallback()
    {
        __this = (Activity) getWeakRefActivity().get();
    }

    private boolean checkContent()
    {
        Activity activity = (Activity) getWeakRefActivity().get();
        if(activity == null || activity.isFinishing())
        {
            return false;
        }
        return true;
    }

    protected boolean isDismissLoadingDataReady()
    {
        return true;
    }

    @Override
    public void onDataReady(@Nullable T data)
    {
        if(checkContent() == false) return;
        if(isDismissLoadingDataReady())
        {
            CommUtil.dismissHUD();
        }
        if(data.Success)
        {
            doProcessData(data);
        }
        else
        {
            CommUtil.alert(
                    __this,
                    null,
                    data.Msg);
        }
    }

    public abstract void doProcessData(T data);
}

 

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