學習筆記,僅供參考
收集的泛型Blog:泛型
泛型
泛型的概述
- 泛型概述
- 通常而言我們只會使用容器來存儲一種類型的對象。泛型的主要目的之一就是用來指定容器要持有什麼類型的,因此與其使用Object,我們更喜歡暫時不指定類型,而是稍後再決定具體使用什麼類型。要達到這個目的,需要使用類型參數,用尖括號括住,放在類名後面。然後在使用這個類的時候,再用實際的類型替換此類型參數。
- 泛型好處
- 提高安全性(將運行期的錯誤轉換到編譯期)
- 省去強轉的麻煩
- 泛型基本使用
<>
中放的必須是引用數據類型
舉個例子
我在ArrayList中放多種數據類型,代碼如下:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(110);
list.add(true);
list.add(new Person("張三", 23));
list.add(new Person("李四", 24));
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
輸出:
110
true
Person [name=張三, age=23]
Person [name=李四, age=24]
現在,我想調用集合中元素的getName方法。由於,Person的父類Object類中不存在getName方法,所以我們需要對元素進行強制向下轉型:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(110);
list.add(true);
list.add(new Person("張三", 23));
list.add(new Person("李四", 24));
Iterator it = list.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
報錯信息:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to com.guiyang.bean.Person
at com.guiyang.restudy3.D1Genric.main(D1Genric.java:19)
ClassCastException異常,是JVM在檢測到兩個類型間轉換不兼容時引發的運行時異常。
在上面的代碼中,我們引發了ClassCastException異常,這是由於我們試圖對Integer強制轉換爲Person類時發生的異常,這個異常在編譯時沒有顯露出來。
如果我想讓這個錯誤在編譯階段就暴露,我就需要用到泛型,規定只有Person類及其子類可以進入ArrayList:
ArrayList<Person> list = new ArrayList<Person>();
當我們給ArrayList加上泛型之後,Java就會提示我們出現了編譯時錯誤:
我們把這倆行代碼刪除後,再運行:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("張三", 23));
list.add(new Person("李四", 24));
Iterator<Person> it = list.iterator();
while(it.hasNext()) {
Person p = it.next();
//由於我們利用泛型獲取到的都是Person對象,所以就可以不用向下強轉了
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
輸出:
張三...23
李四...24
- 注意事項
前後泛型必須一致,下面,我們分別列出了正確的和錯誤的寫法:
//正確的(前後一致)
ArrayList<Person> list = new ArrayList<Person>();
//錯誤的(前後不一致)
ArrayList<Person> list = new ArrayList<Object>();
當我們在前面定義過泛型之後,後面的泛型可以不定義,若定義了,則前後必須一致:
//正確的(前定義,後不定義)
ArrayList<Person> list = new ArrayList<>();
最後,注意泛型最好不要定義爲Object,不會報錯,但是沒意義:
//沒意義
ArrayList<Object> list = new ArrayList<>();