Java泛型類


使用泛型(也叫通用),可以在不知道程式碼操作的物件的型別的情況下編寫程式碼。 它允許建立通用類,建構函式和方法。泛型類是使用形式型別引數定義的。
形式型別引數是一個逗號分隔的變數名列表,放在類宣告中類名後的尖括號<>中。

語法

下面的程式碼宣告一個類Wrapper,它接受一個形式型別引數:

public class Wrapper<T>  {

}

上程式碼中,引數已命名為TT是一個型別變數,它可以是Java中的任何參照型別,例如:StringIntegerDouble等。

當使用Wrapper類時,要指定形式型別引數值。

實際引數

採用形式型別引數的類也稱為引數化類。可以宣告Wrapper類的變數,將String型別指定為其形式型別引數的值,如下所示。

Wrapper<String> stringWrapper;

這裡,String是實際的型別引數。
Java允許使用一個泛型類不指定形式型別引數。

用法

這是為了向後相容。還可以宣告Wrapper <T>類的變數,如下所示:

Wrapper  aRawWrapper;

當使用通用類而不指定實際的型別引數時,它被稱為原始型別。 上面的宣告使用Wrapper <T>類作為原始型別,因為它沒有指定T型別的值。

通用類的實際型別引數必須是參照型別。原始型別不允許作為通用類的實際型別引數。
類可以採用多個正式型別引數。 下面的程式碼宣告一個Mapper類,它接受兩個形式引數TR

public class Mapper<T, R>    {

}

可以宣告Mapper <T,R>類的變數如下:

Mapper<String, Integer>  mapper;

這裡,實際的型別引數是StringInteger。形式型別引數在類體中可用作型別。

public class Wrapper<T> {
  private T obj;

  public Wrapper(T obj) {
    this.obj = obj;
  }

  public T get() {
    return obj;
  }

  public void set(T obj) {
    this.obj = obj;
  }
}

Wrapper <T>類使用形式型別引數來宣告範例變數obj,以宣告其建構函式和set()方法的形式引數,以及作為get()方法的返回型別。

可以通過為建構函式指定實際的型別引數來建立泛型型別的物件,如下所示:

Wrapper<String> w1  = new Wrapper<String>("Hello");

也可以省略實際的型別引數。 在下面的程式碼中,省略指定String型別,編譯器會將建構函式的實際型別引數推斷為String

Wrapper<String> w1  = new Wrapper<>("Hello");

當宣告了泛型類的一個變數,可以把形式型別引數看作是指定的實際型別引數。現在,可以認為,對於w1Wrapper類的get()方法返回一個String

String s1=  w1.get();

範例

以下程式碼顯示如何使用Wrapper類。

public class Main {
  public static void main(String[] args) {
    Wrapper<String> w1 = new Wrapper<>("Hello");
    String s1 = w1.get();
    System.out.println("s1=" + s1);

    w1.set("Testing generics");
    String s2 = w1.get();
    System.out.println("s2=" + s2);

    w1.set(null);
    String s3 = w1.get();
    System.out.println("s3=" + s3);
  }
}

class Wrapper<T> {
  private T obj;

  public Wrapper(T obj) {
    this.obj = obj;
  }

  public T get() {
    return obj;
  }

  public void set(T obj) {
    this.obj = obj;
  }
}

執行上面程式碼,輸出結果如下 -

s1=Hello
s2=Testing generics
s3=null