注:參考書籍:Java語言程序設計。本篇文章爲讀書筆記,供你們參考學習使用java
1.使用泛型的主要優勢是可以在編譯時而不是在運行時檢查出錯誤,提升了代碼的安全性和可讀性,同時也提升了代碼的複用性。數組
1.1如何理解泛型的使用提升了代碼的安全性?安全
答:例如這樣一段代碼:函數
ArrayList<Date> arrayList = new ArrayList<Date>();學習
arrayList.add(new Date());設計
arrayList.add(「data」);對象
這段代碼在編譯時會報錯,由於ArrayList只能存儲同一種類型的數據。接口
若是這段代碼更改成非泛型類型的話,以下:ci
ArrayList arrayList = new ArrayList();element
arrayList.add(new Date());
arrayList.add(「data」);
而這段代碼在編譯時就不會報錯,而是在運行時會出現出錯,因此,使用泛型能夠提升代碼的安全性。
1.2如何理解提升了代碼的複用性?
答:例如,建立一個泛型公共方法,則這個方法就能夠處理多種數據類型,沒必要再爲每一種數據類型單獨的編寫方法,故提升了代碼的複用性。
2.定義泛型類
方法:在類名後面添加兩個尖括號,在尖括號中填寫類型形參(此時的類型形參通常使用T或者E,固然也能夠使用其餘的標識),多個形參之間使用逗號隔開,例如:
public class GenericStack<T>{
}
警告:假設建立一個上面類的對象,形式爲:GenericStack<String> genericStack = new GenericStack<String>();這可能會誤導咱們認爲GenericStack的構造函數爲public GenericStack<T>();其實這是錯誤的,它的構造函數應該爲:public GenericStack();
能夠定義一個類或者一個接口做爲泛型或者接口的子類型。例如,在Java API中,java.lang.String類被定義爲實現了Comparable接口,以下所示:
public class String implements Comparable<String>
3.定義泛型方法
格式:在方法的返回類型前添加一對尖括號,而後在尖括號中填寫類型形參,多個類型形參之間使用逗號隔開。爲了調用泛型方法,須要將實際類型放在尖括號內做爲方法名的前綴,例如:
GenericMethodDemo.<Integer>print(integers);
GenericMethodDemo.<String>print(strings);
4.受限的泛型類型:將泛型指定爲另外一種類型的字類型
例如:public <E extends GeometricObject> boolean equalArea(){}
注:非受限類型<E>和受限類型<E extends Object>是同樣的。
5.原始類型:不使用類型參數的泛型類稱爲原始類型(raw type);
6.通配泛型:通配泛型有3中形式:?、?extends T、? super T。
第一種形式稱爲非受限通配(unbounded wildcard),它和? extends Object效果同樣
第二種形式稱爲受限通配(bounded wildcard),它表示T或者T的一個未知字類型
第三種形式稱爲下線通配(lower-bound wildcard),表示T或T的一個未知父類型
7.泛型消除和對泛型的限制
泛型是使用一種稱爲類型消除的方法來實現的。編譯器使用泛型類型消息來編譯代碼,可是隨後會消除它。所以,泛型信息在運行時是不可用的。這種方法能夠使泛型代碼向後兼容使用原始類型的遺留代碼。
因爲泛型類型在運行時被消除,所以,對於如何使用泛型類型是有一些限制的:
限制1:不能使用new E();
由於運行時執行的是new E(),可是運行時泛型類型E是不可用的。
限制2:不能使用new E[],不能使用泛型類型參數建立數組
E[] elements = new E[capacity];
能夠經過建立一個Object類型的數組,而後將它的類型轉換爲E[]來規避這個限制,以下所示
E[] elements = (E[])new Object[capacity];
可是這種使用類型轉化的方式會致使一個免檢的編譯警告。該警告之因此出現是由於編譯器沒法確保在運行時類型轉換是否成功。這種類型的編譯警告是對java泛型的限制,也是沒法避免的。
不容許使用泛型類建立泛型數組,例如,下面的代碼是錯誤的:
ArrayList<String>[] list = new ArrayList<String>[10];
能夠使用下面的代碼來規避這種限制:
ArrayList<String>[] list = (ArrayList<String>[])new ArrayList[10];
這樣會獲得一個警告。
限制3:在靜態環境下不容許類的參數是泛型類型
因爲泛型類的全部實例都有相同的運行時類,因此泛型類的靜態變量和方法是被它的全部實例所共享的。所以,在靜態方法中、數據域、或者初始化語句中,爲了類而引用類型參數是非法的。例如,下面的代碼是非法的:
public class Test<E>{
public static void m(E ol){ //非法
}
public static E ol; //非法
static{
E o2;//非法
}
}
限制4:異常類不能是泛型的