泛型的基本概念及優點
泛型:指參數化類型的能力
優點:(1)、能夠在編譯時而不是運行時檢測出錯誤 (2)、提高軟件的可靠性和可讀性
用途:可以定義帶泛型的類、接口和方法
- 定義帶泛型的類和接口時,需要將泛型類型放在類名和接口名之後
示例
public class A<E>{
private Stack<E> s = new Stack<E>();
public E peek(){
return s.peek();
}
public void push(E e){
s.push(E);
}
}
2、定義一個帶泛型的方法時,要將泛型類型放在方法返回類型之前
示例
public class A{
public static <E> void print(E[] e){
for(int i=0;i<e.length;i++)
System.out.println(e[i]);
}
}
//調用時
A.<Integer>print(integers); //integer = new Integer[10]
A.<String>print(strings); //strings = new String[10]
通配泛型
引入通配泛型的原因:
假設類A 有方法 public static void a(B < Object > b)
定義B的一個實例 B< Integer > b = new B< Integer >();
A.a(b) 調用會報錯
原因:
儘管Integer 是Object 子類型,但B< Integer > 並不是B< Object > 的子類型
針對上面的情況,就需要引入通配泛型
通配泛型分類
- 非受限通配:< ? > 等價於 < ? extends Object >
- 受限通配: < ? extends T > T 或 T 的子類型
- 下限通配: < ? super T > T 或 T 的父類型
示例
public class Demo{
public static void main(String[] args){
Stack<Integer> intStack = new Stack<Integer>();
intStack.push(1);
intStack.push(2);
intStack.push(3);
print(intStack);
}
public static void print(Stack<? extends Number> stack){ //Number及其子類型
while(!stack.isEmpty())
System.out.println(stack.pop());
}
}
泛型使用過程中的注意事項
不能使用new E (); 即:不能使用泛型類型參數創建實例
原因:泛型是使用一種類型消除的方法來實現的,編譯器使用泛型信息來編譯代碼,但是隨後會清除它。
示例public class A<E>{ E e = new E(); //非法操作 }
不能使用new E[ ] 即:不能使用泛型類型參數創建數組
示例public class A<E>{ E[] ele = new E[10]; //非法操作 //可使用下面的方式進行規避 E[] ele = (E[]) new Object[10]; //合法 ArrayList<String> list = new ArrayList<String>[10]; //非法操作 //可使用下面的方式進行規避 ArrayList<String> list = (ArrayList<String>) new ArrayList[10] //合法 }
靜態方法、數據域、初始化語句中爲了類二引入泛型類型參數是非法的
示例public class A<E>{ ststic{ E e1; //非法 } public static void b(E e2){ //非法 } public static E e3; //非法 }
異常類不能是泛型的
示例public class MyException<T> extends Exception{ //非法 }