java進階(一):泛型
1、泛型簡介
所謂泛型,即通過引數化型別來實現在同一份程式碼上操作多種資料型別,泛型程式設計是一種程式設計正規化,他利用“引數化型別”將型別抽象化,從而實現更為靈活的複用。
先簡單給個例子:
//可以想象這裡的T為Integer型別,以便於理解,其實它可以是任何型別 public class GenClass<T>{ private T obj; public GenClass (T obj){ this.obj = obj; } public T getObj(){ return obj; } public void setObj(T obj){ this.obj = obj; } }
注: 1、可以想象這裡的T為Integer型別,以便於理解,其實它可以是任何型別。 2、泛型可以在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的。
2、泛型示例
在上面的例子中,引數T就是我們所說的型別引數,類GenClass即為泛型類,值得注意的是:
1、泛型的型別引數可以是泛型類 2、泛型類可以同時設定多個型別引數 3、泛型類可以繼承泛型類 4、泛型類可以實現泛型介面
示例一:
GenClass<GenClass<Student>> gen3 = new GenClass<GenClass<Student>>(); GenClass<Student> gen4 = new GenClass<Student>(); gen4.setData(new Student("張三")); gen3.setData(gen4); System.out.println(gen3.getData().getData().toString());
示例二:
class SubClass<T1,T2> extends SuperClass<T1> {
private T2 var2;
public SubClass(T1 var1,T2 var2){
super(var1);
this.var2 = var2;
}
}
注: 1、不能拿泛型變數加上泛型變數(T1+T1) 2、不能建立泛型陣列(private T[] = new T[10];)
3、限制泛型可用型別
在定義泛型類別時,預設在例項化泛型類的時候可以使用任何型別,但如果想要限制使用泛型型別時,即只能用某種特定型別或其子型別才能例項化該型別時,可以使用extends關鍵字指定這個型別必須是繼承某個類,或實現某個介面(也用extends關鍵字,而不用implements)。
示例如下:
class GenericClass<T extends Animal>{
...
}
上述例子限制了泛型類接收的引數,只能接受Animal類或其子類。
4、型別通配宣告
同一泛型類,如果例項化時給定的實際型別引數不同,則這些例項的型別是不相容的,不能相互賦值,如:
GenericClass<Boolean> f1 = new GenericClass<Boolean>();
GenericClass<Integer> f2 = new GenericClass<Integer>();
f1 = f2; //報錯
這種情況下,我們可以用泛型萬用字元宣告型別引數,如:
GenericClass<Boolean> f1 = new GenericClass<Boolean>();
GenericClass<?> f2 = f1; //成功賦值
和限定泛型的上限相似,可以用extends關鍵字限定?萬用字元的上限,用super限定?萬用字元的下限,如:
GenericClass<Animal> f1 = new GenericClass<Animal>();
GenericClass<? extends Animal> f2 = f1;
GenericClass<? superDog> f2 = f1;
5、泛型方法
不僅類可以宣告泛型,類中的方法也可宣告僅用於自身的泛型,這種方法便稱為泛型方法,例如:
public <T1,T2> T1 getData(T1 var1 , T2 var2) {
T1 var = var1;
return var;
}
在泛型列表<>中宣告的泛型,可以用於該方法的返回型別宣告、引數型別的宣告和方法中區域性變數的型別宣告,但類中的其他方法不能使用當前方法宣告的泛型。值得注意的是,是否擁有泛型方法,與其所在類是否是泛型類無關。