一、泛型的主要優點是能在編譯時檢測出類型錯誤而不是在運行時檢測出錯誤。
二、泛型類型必須是引用類型,即基本類型不能作爲泛型類型。
三、定義泛型類、接口和方法
1.構造方法應該是public ClassName()而不是public ClassName<E>()
2.可以爲靜態方法定義泛型類型
聲明泛型方法 public static <E> void methodName(E){}
調用泛型方法 method(params),編譯器自動發現實際類型
四、通配泛型
1.<?>非受限通配 等價於 <? extends Object>
2.<? extends T> 表示T或T的子類
3.<? super T> 表示T或T的父類
注意: 雖然Integer是Object的子類,但是ClassName(Integer)並不是ClassName(Object)的子類!!
五、消除泛型和對泛型的限制
1.編譯器使用泛型類型信息來編譯代碼, 但隨後就會消除它,所以泛型信息在運行時是不可用的。例如:
ArrayList<String> list = new ArrayList();
list.add("abc")
String state = list.get(0)
等價於
ArrayList list = new ArrayList();
list.add("abc")
String state = (String)( list.get(0))
2.如果泛型類型是受限的,編譯器會使用受限類型來替換它。例如:
public static <E extens SomeObject> boolean isEqual(E o1, E o2){
return o1.getArea() == o2.getArea()
}
等價於
public static <SomeObject> boolean isEqual(SomeObject o1, SomeObject o2){
return o1.getArea() == o2.getArea() }
3.無論實際類型是什麼,泛型類是被他的所有實例所共享的。例如:
ArrayList<String> list1 = new ArrayLsit();
ArrayList<Integer> list1 = new ArrayLsit();
在運行時只有一個ArrayList類加載到JVM中,而list1 instanceof ArrayList<String>是錯誤的,因爲沒有ArrayList<String>這個類加載到JVM中
4.因爲泛型類型在運行時被消除,所以對使用泛型有一些限制:
I.不能new E(), 不能使用泛型類型參數創建實例
II.不能new E[], 不能使用泛型類型參數創建數組, 但可以E[] list = (E[])new Object[capacity]
III.靜態上下文中不允許類的參數是泛型類型
public class Test <E>{
public static void m(E o1){} //illegal
public static E o1; //illegal
static{
E o1; //illegal
}
IV.不能再異常類中使用泛型參數
public class MyException<E> extends Exception{} //illegal