1. 程式人生 > >java進階(一):泛型

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;
}

在泛型列表<>中宣告的泛型,可以用於該方法的返回型別宣告、引數型別的宣告和方法中區域性變數的型別宣告,但類中的其他方法不能使用當前方法宣告的泛型。值得注意的是,是否擁有泛型方法,與其所在類是否是泛型類無關。