1. 程式人生 > >Java泛型相關總結(下)

Java泛型相關總結(下)

數組類 urn gpa ply 可變參數 function 這樣的 ava manage

約束與局限性

不能用基本類型實例化類型參數

不能像Pair<double>這樣調用,只能Pair<Double>,原因是類型擦除

運行時類型查詢只使用於原始類型

虛擬機中的對象屬於一個特定的非泛型類型,類型查詢只能產生原始類型。

Pair<String> stringPair = ...;
Pair<Employee> employeePair = ...;
if (stringPair.getClass() == employeePair.getClass()) //相等的

不能創建參數化類型的數組

因為類型擦除會導致數組元素類型不安全

不能創建數組,但可以聲明類型為Pair<String>[]的變量

向可變參數方法傳遞泛型類型實例,虛擬機會創建泛型類型數組,且會提示一個警告,使用@SupressWarnings("unchecked")或@SafeVarargs標註。

不能實例化類型變量
不能使用 new T(...)、new T[...]、T.class這樣的類型變量

不能構造泛型數組
這裏有數組中的一個知識點,數組類型之間不能強制類型轉換,當Object[]引用賦給Comparable[]變量時,將會發生ClassCastException異常
擦除導致的
在靜態方法中,構造靜態方法有兩種方式:
1.讓用戶提供數組構造器方法

public static <T extends Comparable> T[] minmax(IntFunction<T[]> constr, T... a) {
    T[] mm = constr.apply(2);
    ...
}

2.使用反射

private static <T extends Comparable> T[] minmax2(T... args) {
    T[] mm = (T[])Array.newInstance(args.getClass().getComponentType(), 2);
    ...
}

不能在靜態域、靜態方法中引用類型變量

會有編譯時錯誤


不能拋出或捕獲泛型類的對象,泛型類擴展Throwable是不合法的

可以消除對受查異常的檢查


擦除後的沖突,比如以下泛型方法在擦除後會與Object的equals()產生沖突
public boolean equals(T value) {
return first.equals(value);
}
補救的辦法是重新命名引發錯誤的方法。


泛型的繼承規則

無論S與T有什麽關系,Pair<S>與Pair<T>沒有什麽關系,以下代碼有編譯錯誤

Manager[] topHonchos = ...;
Pair<Employee> result = ArrayAlg.minmax(topHonchos); //error

在數組中,可以將一個Manager[]對象賦予一個Employee[]的變量,但虛擬機會監控數組元素的類型,如果試圖將一個Employee對象存儲到該數組中,會拋出ArrayStoreException異常

可以將參數化類型轉化為原始類型,Pair<Employee>是原始類型Pair的子類。

泛型類可以擴展或實現其他泛型類,如ArrayList<Employee>類實現List<Employee>接口。

通配符類型

通配符類型,允許類型參數變化,定義如下。

Pair<? extends Employee>

此時的繼承關系是,Pair<Employee> 或 Pair<Manager> > Pair<? extends Employee > Pair(原始類型)

超類型限定(supertype bound)

Pair<? super Manager>

超類型限定限制為Manager的所有超類型。

帶有超類型限定的通配符可以向泛型對象寫入,帶有子類型限定的通配符可以從泛型對象讀取。

Java泛型相關總結(下)