集合中可以存儲任意類型對象,但是在取出時,如果要使用具體對象的特有方法時,需要進行向下轉型,如果存儲的對象類型不一致,在轉型過程中就會出現ClassCastException異常。這樣就給程序帶來了不安全性。
在jdk1.5以後就有了解決方案——泛型技術:在存儲元素時,就不允許存儲不同類型的元素。存儲了就編譯失敗。 所以就需要在存儲元素時,在容器上明確具體的元素類型,這其實和數組定義很像。
1)將運行時期的ClassCastException異常轉移到了編譯時期,進行檢查,並以編譯失敗來體現。 這樣有利於程序員儘早解決問題。
2)避免了向下轉型(強轉)的麻煩。
只要在使用類或者接口時,該類或者接口在api文檔描述時都帶着<>,就需要在使用時定義泛型。
其實,泛型無非就是通過<>定義了一個形式參數,專門用於接收具體的引用類型。在使用時,一定要傳遞對應的實際參數類型。
集合中泛型的應用特別多見。
泛型技術是用於編譯時期的技術,編譯器會按照<>中的指定類型對元素進行檢查,檢查不匹配,就編譯失敗,匹配,就編譯通過,通過後,生產的class文件中是沒有泛型的,這就成爲泛型的擦除。
運行時,可以根據具體的元素對象獲取其具體的類型,並用該類型對元素進行自動轉換。
//演示泛型的好處之一:沒采用泛弄,對元素的處理不安全。泛型可以把運行期的錯誤提前到編譯期
public static void t1(){
//List list = new ArrayList();//無泛型
List<String> list = new ArrayList<String>();//無泛型
list.add("aaaqqqq");
list.add("abaqqqq");
list.add("cccqqqq");
//list.add(100); //無泛型時,此處不會報錯,但有泛型時會報錯。
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
String str = (String)obj;
str = str.substring(1, 4);
System.out.println(str);
}
}
//演示泛型的好處之二:從集合中讀取的數據不需要強轉,能夠自動識別
public static void t2(){
//List list = new ArrayList();//無泛型
List<String> list = new ArrayList<String>();
list.add("aaaqqqq");
list.add("abaqqqq");
list.add("cccqqqq");
Iterator<String> it = list.iterator();
while(it.hasNext()){
//String str =(String) it.next();//無泛型,必須強轉
String str = it.next();//List有泛型,並且Iterator也加泛型,那麼這裏就不用強轉.
str = str.substring(2);
System.out.println(str);
}
System.out.println("------------");
for(Object obj:list){
System.out.println(obj);
}
//※泛型的好處之二:從集合中讀取的數據不需要強轉,能夠自動識別
for(String str:list){
System.out.println(str);
}
}
自己可以定義一個加泛型的類public class MySet<E> {}此時該類能接受指定的類型,E 形式類參數