通配符類型
通配符類型中, 允許類型參數變化。 例如, 通配符類型
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>。