泛型瑣碎之泛型方法

泛型

泛型:是一種把類型明確的工作推遲到創(chuàng)建對象或者調(diào)用方法的時候才去明確的特殊的類型。把類型當(dāng)作參數(shù)傳遞。

格式:<數(shù)據(jù)類型> 此處的數(shù)據(jù)類型只能是引用類型, 如<E>, 丟進(jìn)去的類型必須是E的對象或其子類的對象。

好處:
A:把運行時期的問題提前到了編譯期間
B:避免了強(qiáng)制類型轉(zhuǎn)換
C:優(yōu)化了程序設(shè)計,解決了黃色警告線

泛型方法

such as, ResponseEntity類帶有一個E類型形參

public class ResponseEntity<E> {
    private String msg;
    private String code; 
    private E data;
    
    public ResponseEntity(String code, String msg, E data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    
    /*
    方法靜態(tài)時,不能訪問類定義上的泛型
    */
    public static <E> ResponseEntity<E> success(String code, String msg, E data) {
    // 傳入什么類型,E就是什么類型 
        return new ResponseEntity<E>(code, msg, data);
    }
} 

現(xiàn)在假設(shè)有一個

Apple a = new Apple();
// 調(diào)用success()方法, 
ResponseEntity.success("200", "ok", a);
//這樣success()方法的返回值類型 ResponseEntity<E>中的E代表Apple類型。

再比如:

public static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    for (T o : a) {
        c.add(o);
    }
}

這是一個泛型方法,該泛型方法定義一個T類型形參,這樣方法就能接受任意類型的參數(shù)了。

Integer[] ia = new Integer[100];
Collection<Number>  cn = new ArrayList<>();
// T代表Number類型
// 只比較泛型形參: Collection<T> cn
fromArrayToCollection(ia, cn);

cn是Collection<Number>類型,與此方法的方法簽名進(jìn)行比較——只比較泛型參數(shù),故該T類型形參代表了Number類型。

public static <T> void test(Collection<? extends T> from, Collection<T> to) {
    for (T ele : from) {
        to.add(ele);
    }
}

//String Object
List<Object> ao = new ArrayList<>();
List<String> as = new ArrayList<>();
// T代表Object類型, as中的String是Object的子類類型
test(as, ao);

泛型方法和類型通配符(?)

大多時候,可以使用泛型方法來代替類型通配符。如Java的Collection接口中的兩個方法:

// 泛型通配符
public interface Collection<E> {
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
}

//采用泛型方法的形式
public interface Collection<E> {
    <T> boolean containsAll(Collection<T> c);
    <T extends E> boolean addAll(Collection<T> c);
}

上面兩個方法中類型形參T只使用了一次,類型形參T產(chǎn)生的唯一效果是可以在不同的調(diào)用點傳入不同的實際類型。對于這種情況,應(yīng)該使用通配符:通配符就是被設(shè)計用來支持靈活的子類化的。

泛型方法允許類型形參被用來表示方法的一個或多個參數(shù)之間的類型依賴關(guān)系,或者方法返回值與參數(shù)之間的類型依賴關(guān)系。如果沒有這種依賴關(guān)系,就不應(yīng)該使用泛型方法。

再來看一個栗子, Collections.copy()方法:

public class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src){...}
}
/*
src中 ? 代表的類型須是dest中 T 的子類或它本身
dest于src的類型存在明顯的依賴關(guān)系
但JDK定義src時使用的是類型通配符,而不是泛型方法
Reason: 該方法無須向src集合中添加元素,也無須修改src集合里的元素,使用類型通配符,無須使用泛型方法
*/

如果改成泛型方法,不使用類型通配符:

class Collections {
    public static <T, S extends T> void copy(List<T> dest, 
    List<S> src) {...}
}
/*
這里的類型形參S, 它使用了一次, 其他參數(shù)的類型、方法返回值的類型都不依賴于它,
那類型形參S就沒有存在的必要,即可以用通配符來代替S。so Java 設(shè)計該方法時采用了通配符,而不是泛型方法。
*/

類型通配符既可以在方法簽名中定義形參的類型,也可以用于定義變量的類型;但泛型方法中的類型形參必須在對應(yīng)方法中顯式聲明。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • object 變量可指向任何類的實例,這讓你能夠創(chuàng)建可對任何數(shù)據(jù)類型進(jìn)程處理的類。然而,這種方法存在幾個嚴(yán)重的問題...
    CarlDonitz閱讀 1,030評論 0 5
  • 開發(fā)人員在使用泛型的時候,很容易根據(jù)自己的直覺而犯一些錯誤。比如一個方法如果接收List作為形式參數(shù),那么如果嘗試...
    時待吾閱讀 1,128評論 0 3
  • 一、泛型簡介1.引入泛型的目的 了解引入泛型的動機(jī),就先從語法糖開始了解。 語法糖 語法糖(Syntactic S...
    Android進(jìn)階與總結(jié)閱讀 1,079評論 0 9
  • 一、泛型的概念 泛型就是:類型參數(shù)化,處理的數(shù)據(jù)類型不是固定的,而是可以作為參數(shù)傳入;瘋狂講義定義:泛型就是允許在...
    Serenity那年閱讀 760評論 2 0
  • 我以前不是這樣的 一首歌我最多聽五十次 我就膩到連前奏響起我都特別厭惡 我以前不是這樣的 我對一個人的好感不超過三...
    EPARGNer閱讀 284評論 1 0

友情鏈接更多精彩內(nèi)容