使用泛型(也叫通用),可以在不知道代碼操作的對象的類型的情況下編寫代碼。 它允許創(chuàng)建通用類,構(gòu)造函數(shù)和方法。泛型類是使用形式類型參數(shù)定義的。
形式類型參數(shù)是一個逗號分隔的變量名列表,放在類聲明中類名后的尖括號<>
中。
下面的代碼聲明一個類Wrapper
,它接受一個形式類型參數(shù):
public class Wrapper<T> {
}
上代碼中,參數(shù)已命名為T
。T
是一個類型變量,它可以是Java中的任何引用類型,例如:String
,Integer
,Double
等。
當(dāng)使用Wrapper
類時,要指定形式類型參數(shù)值。
采用形式類型參數(shù)的類也稱為參數(shù)化類??梢月暶?code>Wrapper類的變量,將String
類型指定為其形式類型參數(shù)的值,如下所示。
Wrapper<String> stringWrapper;
這里,String
是實(shí)際的類型參數(shù)。
Java允許使用一個泛型類不指定形式類型參數(shù)。
這是為了向后兼容。還可以聲明Wrapper <T>
類的變量,如下所示:
Wrapper aRawWrapper;
當(dāng)使用通用類而不指定實(shí)際的類型參數(shù)時,它被稱為原始類型。 上面的聲明使用Wrapper <T>
類作為原始類型,因為它沒有指定T
類型的值。
通用類的實(shí)際類型參數(shù)必須是引用類型。原始類型不允許作為通用類的實(shí)際類型參數(shù)。
類可以采用多個正式類型參數(shù)。 下面的代碼聲明一個Mapper
類,它接受兩個形式參數(shù)T
和R
:
public class Mapper<T, R> {
}
可以聲明Mapper <T,R>
類的變量如下:
Mapper<String, Integer> mapper;
這里,實(shí)際的類型參數(shù)是String
和Integer
。形式類型參數(shù)在類體中可用作類型。
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>
類使用形式類型參數(shù)來聲明實(shí)例變量obj
,以聲明其構(gòu)造函數(shù)和set()
方法的形式參數(shù),以及作為get()
方法的返回類型。
可以通過為構(gòu)造函數(shù)指定實(shí)際的類型參數(shù)來創(chuàng)建泛型類型的對象,如下所示:
Wrapper<String> w1 = new Wrapper<String>("Hello");
也可以省略實(shí)際的類型參數(shù)。 在下面的代碼中,省略指定String
類型,編譯器會將構(gòu)造函數(shù)的實(shí)際類型參數(shù)推斷為String
:
Wrapper<String> w1 = new Wrapper<>("Hello");
當(dāng)聲明了泛型類的一個變量,可以把形式類型參數(shù)看作是指定的實(shí)際類型參數(shù)。現(xiàn)在,可以認(rèn)為,對于w1
,Wrapper
類的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;
}
}
執(zhí)行上面代碼,輸出結(jié)果如下 -
s1=Hello
s2=Testing generics
s3=null