在擁有泛型以前,泛型程序設計是由繼承實現的。好比:arraylist,在擁有泛型以前arraylist其實只維護一個object引用的數組。java
使用繼承的問題在於獲取值時必須強制類型轉換,編譯器也沒法檢查傳入參數類型。c++
因此泛型類的好處在於:使程序擁有更好的安全性和可讀性。數組
public class A<T> { private T first; private T second; public A(T first,T second){ this.first=first; this.second=second; } }
類型變量通常使用大寫,且比較短。java庫中,E表明集合類中的元素類型,K和V分別表明表的關鍵字與值得類型。T表明任意類型。安全
泛型類能夠看做是普通類工廠。測試
能夠在普通類中定義一個泛型方法。this
class A{ public static <T> T f(T a){ return a; } }
須要對類型變量加以約束時使用extens,好比:翻譯
public static <T extends Comparable> T min(T[]a)...
此時min方法只能被實現了Comparable接口的類的數組調用。限制多個接口時使用&隔開。設計
泛型類型會被擦除,替換位限定類型,若是沒有限定類型則使用Object。因此java中不會出現c++中的模板代碼膨脹(每一個模板的實例化會產型不通的類型)code
爲了提高效率,應該將標籤接口放在邊界列表的尾部,由於若是將非標籤接口放在後面。編譯器要在必要時插入強制類型轉換。對象
使用類型擦除實現泛型的最主要動機爲使泛化的客戶端可使用非泛化的類庫,反之亦然,這是遷移兼容性,爲了兼容jdk1.5以前的類庫,而且保證當一個庫轉變爲泛型以後不會影響到依賴於它的代碼和程序.
擦除返回類型後,編譯器要插入強制類型轉化。
類型擦除後會有兩個不一樣的方法,因此編譯器就要生成橋方法。
基本是由類型擦除引發的
類型擦除後 object不能存儲基本類型的值
虛擬機中的對象總有一個特定的非泛型類型,所以全部的類型查詢只產生原始類型。
if(a instanceof Pair<T>)//ERROR
只能測試a是不是一個任意類型的pair
如Pair<String>[] table = new Pair<String>[10];//ERROR
可是能夠聲明通配類型的數組而後類型轉換。
Pair<String>[] table = (Pair<String>[])new Pair<?>[10];
可是結果並不安全,推薦使用ArrayList<Pair<String>>
### 類型擦除的補償
可讓泛型類保有一個Class對象,在初始化時傳入一個Class對象,轉而使用動態的isInstance()方法檢測類型代替不可以使用的instanceof.
也可使用class對象.newInstance()建立實例,代替不可用的new關鍵字