近來重溫了一下《Core Java》中的第8章,關于泛型的描述,重拾了一下之前的知識和了解,總結幾點思考和感悟如下:
-
泛型的聲明
在類或者方法的定義過程中,可以進行泛型的聲明(一般用大寫字母T來表示),以便類或者方法的後續編寫過程中可以使用這個T作為特定類的表示。
-
泛型在類定義時的聲明
public class Pair<T> {
private T first;
private T second;
public T getFirst(){}
public T getSecond(){}
public void setFirst(T first){
this.first = first;
}
public void setSecond(T second){
this.second = second;
}
}
跟在Pair後在尖括号中的T就是類定義中泛型的聲明。
-
泛型在方法定義時的聲明
類似的,方法定義過程中也可以進行泛型的聲明,一般是在方法的modifiers後傳回值前。
public class MethodGeneric{
public static <T> T printAndReturn(T t){
System.out.println("do nothing then return input parameter.");
return t;
}
}
值得注意的有2點:
注意點1,泛型類型可以繼承1個類并同時實作若幹個接口,均用關鍵字extends來表示,繼承的父類(僅能繼承1個)必須放在extends後第一位,實作多個接口用&連接配接起來,如下代碼所示:
public class GenericExtends<T extends BaseClass & Comparable & Serializable> {
//class body
}
注意點2,泛型T是一種編譯時的概念,而不是運作時的概念。也就是說在Java虛拟機運作時是沒有泛型的概念的,統一為Object類或者泛型T所繼承的類或者實作的接口(一般替換為聲明時extends後的第一個)。編譯時會在必要的return等地方根據使用泛型時傳入的具體類型做強制類型轉換。
-
泛型的上界和下界
說到泛型的上界和下界,必須提到通配符(wildcard——”?“)。為了友善說明,我們定義兩個類:父類Father和子類Son,以及泛型類Pair。
public class Pair<T> {
private T first;
private T second;
public T getFirst(){}
public T getSecond(){}
public void setFirst(T first){
this.first = first;
}
public void setSecond(T second){
this.second = second;
}
}
class Father{}
class Son extends Father{}
首先是泛型的上界,例如? extends Father,這裡需要特别注意的是此處是使用泛型時這個具體傳給T的類型必須是Father的子類。使用上界時可以用get方法,而無法使用set方法,這個具體該怎麼了解呢,我們看一下的案例
public static void main(String[] args){
Pair<? extends Father> p = new Pair<>();
p.getFirst(); //OK
Son s = p.getFirst(); //Error,T為Fahter的子類,是以getFirst()可能回傳Father或者Son,是以不能用Son來接收,隻能用Father來接收。
Father f = p.getFirst(); //OK
p.setFiert(new Father());
//Error,因為此時Pair中的類型T是必須是Father的子類,但是并不知道具體是哪一個子類,究竟是Father還是Son,不明确,是以無法傳具體的類型給T。
}