java核心技術卷I-泛型(二)

通配符類型

通配符類型中, 允許類型參數變化。 例如, 通配符類型

Pair<? extends Employee>

表示任何泛型 Pair 類型, 它的類型參數是 Employee 的子類, 如 Pair<Manager>, 但不是Pair<String>

? extends Employee getFirst()
void setFirst(? extends Employee)

這樣將不可能調用 setFirst 方法,編譯器只知道需要某個 Employee 的子類型,但不知道具體是什麼類型,它拒絕傳遞任何特定的類型
使用 getFirst 就不存在這個問題: 將 getFirst 的返回值賦給一個 Employee 的引用完全合法
在這裏插入圖片描述

通配符的超類型限定

通配符限定與類型變量限定十分類似,但是,還有一個附加的能力,即可以指定一個超
類型限定 (supertypebound)

? super Manager

這個通配符限制爲 Manager 的所有超類型,可以爲方法提供參數, 但不能使用返回值。
例如, Pair<? super Manager> 有方法

void setFirst(? super Manager)
? super Manager getFirst()

編譯器無法知道 setFirst 方法的具體類型, 因此調用這個方法時不能接受類型爲Employee 或 Object 的參數。 只能傳遞Manager 類型的對象,或者某個子類型(如 Executive) 對象。另外, 如果調用 getFirst, 不能保證返回對象的類型。只能把它賦給一個 Object。

無限定通配符

類型 Pair<?> 有以下方法:

? getFirst()
void setFirst(?)

getFirst 的返回值只能賦給一個 Object。setFirst 方法不能被調用, 甚至不能用 Object 調用。Pair<?> 和 Pair 本質的不同在於: 可以用任意 Object 對象調用原始 Pair 類的 setObject方法。

通配符捕獲

編寫一個交換成對元素的方法:

public static void swap(Pair<?> p)

通配符不是類型變量, 因此, 不能在編寫代碼中使用“ ?” 作爲一種類型。 也就是說, 下述代碼是非法的

? t = p.getFirst(); // Error
p.setFirst(p);
p.setSecond(t);

反射和泛型

反射允許你在運行時分析任意的對象。如果對象是泛型類的實例,關於泛型類型參數則得不到太多信息,因爲它們會被擦除。

泛型Class類

類型參數十分有用, 這是因爲它允許 ClaSS方法的返回類型更加具有針對性。下面Class<T> 中的方法就使用了類型參數

T newInstance()
返回無參數構造器構造的一個新實例。
T cast(Object obj)
如果obj爲 null 或有可能轉換成類型 T,則返回obj ; 否則拋出BadCastException異常。
T[] getEnumConstants() 5.0
如果 T 是枚舉類型, 則返回所有值組成的數組,否則返回 mill。
Class<? super T> getSuperclass()
返回這個類的超類。如果 T 不是一個類或 Object 類,則返回 null。
Constructor<T> getConstructor(Class. ..parameterTypes) 1.1
Constructor<T> getDeclaredConstructor(Class. . . parameterTypes) 1.1
獲得公有的構造器, 或帶有給定參數類型的構造器。
T newlnstance(0bject. . . parameters)
返回用指定參數構造的新實例

使用 Class<T> 參數進行類型匹配

public static <T> Pair<T> makePair(Class<T> c) throws InstantiationException,
IllegalAccessException
{
return new Pair<>(c.newInstance(), c.newInstance());
}
makePair(Employee.class)

Employee.class 是類型 Class 的一個對象。makePair 方法的類型參數 T 同 Employee匹配, 並且編譯器可以推斷出這個方法將返回一個 Pair<Employee>。

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