文章目錄
1.概念
泛型就是參數化型別。泛型的好處是在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的,提高代碼的重用率。
2.案例
1)先看下面案例
//不適用泛型程式設計
Apple app0=new Apple();
Apple app1=new Apple();
List li = new ArrayList();
li.add(app0); //添加非需要類型時發現不了錯誤。
li.add(app1);
Apple appUsed=(Apple)li.get(0);
//使用泛型程式設計如下
Apple app0=new Apple();
Apple app1=new Apple();
List<Apple> li = new ArrayList<Apple>();
li.add(app0); //如果添加的物件類型錯誤,編譯器即可發現。指定容器要持有的物件類型,用編譯器來保證類型的正確性。
li.add(app1);
Apple appUsed=li.get(0);
使用泛型的優點:大型應用時能顯著降低程式的複雜度;泛型為較大的最佳化帶來可能: 可以在編譯期發現該類錯誤,而且在取出元素時不需要再進行類型判斷,從而提高了程式的運行時效率。
2)泛型類
有兩個類如下,要構造兩個類的對象,並列印出各自的成員x。
public class StringFoo {
private String x;
public StringFoo(String x) {
this.x = x;
}
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
}
public class DoubleFoo {
private Double x;
public DoubleFoo(Double x) {
this.x = x;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
}
用泛型來實現
public class GenericsFoo<T> {
private T x;
public GenericsFoo(T x) {
this.x = x;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
}
代碼實現:
public class GenericsFooDemo {
public static void main(String args[]){
GenericsFoo<String> strFoo=new GenericsFoo<String>("Hello Generics!");
GenericsFoo<Double> douFoo=new GenericsFoo<Double>(new Double("33"));
GenericsFoo<Object> objFoo=new GenericsFoo<Object>(new Object());
System.out.println("strFoo.getX="+strFoo.getX());
System.out.println("douFoo.getX="+douFoo.getX());
System.out.println("objFoo.getX="+objFoo.getX());
}
}
3)泛型方法
是否擁有泛型方法,與其所在的類是否泛型沒有關係。要定義泛型方法,只需將泛型參數列表置於傳回值前。
public class ExampleA {
public <T> void f(T x) {
System.out.println(x.getClass().getName());
}
public static void main(String[] args) {
ExampleA ea = new ExampleA();
ea.f("ea ");
ea.f(10);
ea.f('a');
}
}
使用泛型方法時,不必指明參數類型,編譯器會自己找出具體的類型。泛型方法除了定義不同,調用就像普通方法一樣。需要注意,一個static方法,無法訪問泛型類的型別參數,所以,若要static方法需要使用泛型能力,必須使其成為泛型方法。
4)限制泛型和萬用字元
class GenericsFoo<T extends Collection>,這樣類中的泛型T只能是Collection介面的實作類別,傳入非Collection介面編譯會出錯。
class GenericsFoo<? extends Collection>,“?”代表未知類型(萬用字元),這個類型是實現Collection介面。<? extends 類型>表示這個類型是某個類型的子類型。