所謂泛型,就是允許在定義類、介面時通過一個標識表示類中某個屬性的型別或者是某個方法的返回值及引數型別。這個型別引數將在使用時(例如,繼承或實現這個介面,用這個型別宣告變數、建立物件時)確定(即傳入實際的型別引數,也稱為型別實參)。
class Person<T> {
// 使用T型別定義變數
private T info;
// 使用T型別定義一般方法
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
// 使用T型別定義構造器
public Person() {
}
public Person(T info) {
this.info = info;
}
// static的方法中不能宣告泛型
//public static void show(T t) {
//
//}
// 不能在try-catch中使用泛型定義
//public void test() {
//try {
//
//} catch (MyException<T> ex) {
//
//}
//}
}
class Father<T1, T2> {
}
// 子類不保留父類別的泛型
// 1)沒有型別 擦除
class Son1 extends Father {// 等價於class Son extends Father<Object,Object>{
}
// 2)具體型別
class Son2 extends Father<Integer, String> {
}
// 子類保留父類別的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {
}
class Father<T1, T2> {
}
// 子類不保留父類別的泛型
// 1)沒有型別 擦除
class Son<A, B> extends Father{//等價於class Son extends Father<Object,Object>{
}
// 2)具體型別
class Son2<A, B> extends Father<Integer, String> {
}
// 子類保留父類別的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {
}
方法,也可以被泛型化,不管此時定義在其中的類是不是泛型類。在泛型方法中可以定義泛型引數,此時,引數的型別就是傳入資料的型別。
泛型方法的格式:[存取許可權] <泛型> 返回型別 方法名([泛型標識 引數名稱]) 丟擲的異常
public class DAO {
public <E> E get(int id, E e) {
E result = null;
return result;
}
}
如果B是A的一個子型別(子類或者子介面),而G是具有泛型宣告的類或介面,G< B >並不是G< A >的子型別!
比如:String是Object的子類,但是List< String >並不是List< Object >的子類。
public void testGenericAndSubClass() {
Person[] persons = null;
Man[] mans = null;
// 而 Person[] 是 Man[] 的父類別.
persons = mans;
Person p = mans[0];
// 在泛型的集合上
List<Person> personList = null;
List<Man> manList = null;
// personList = manList;(報錯) }
1.使用型別萬用字元:?
比如:List<?> ,Map<?,?>
List<?>是List、List等各種泛型List的父類別。
2.讀取List<?>的物件list中的元素時,永遠是安全的,因為不管list的真實型別是什麼,它包含的都是Object。
3.寫入list中的元素時,不行。因為我們不知道c的元素型別,我們不能向其中新增物件。
■ 唯一的例外是null,它是所有型別的成員
● <?>
允許所有泛型的參照呼叫
● 萬用字元指定上限
上限extends:使用時指定的型別必須是繼承某個類,或者實現某個介面,即<=
● 萬用字元指定下限
下限super:使用時指定的型別不能小於操作的類,即>=
● 舉例:
→ <? extends Number> (無窮小 , Number]
只允許泛型為Number及Number子類的參照呼叫
→ <? super Number> [Number , 無窮大)
只允許泛型為Number及Number父類別的參照呼叫
→ <? extends Comparable>
只允許泛型為實現Comparable介面的實現類的參照呼叫
public static void printCollection3(Collection<? extends Person> coll) {
//Iterator只能用Iterator<?>或Iterator<? extends Person>.why?
Iterator<?> iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
} }
public static void printCollection4(Collection<? super Person> coll) {
//Iterator只能用Iterator<?>或Iterator<? super Person>.why?
Iterator<?> iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
} }