為什么要有泛型?
1.解決元素存儲的安全性問題
2.解決獲取數據元素時,需要類型強轉的問題
服用前:
服用后:
?
? 泛型,JDK1.5新加入的,解決數據類型的安全性問題,其主要原理是在類聲明時通過一個標識表示類中某個屬性的類型或者是某個方法的返回值及參數類型。這樣在類聲明或實例化時只要指定好需要的具體的類型即可。
??????? Java泛型可以保證如果程序在編譯時沒有發出警告,運行時就不會產生ClassCastException異常。同時,代碼更加簡潔、健壯。
使用泛型
泛型的聲明
interface List<T>和class TestGen<K,V>
其中,T,K,V不代表值,而是表示類型。這里使用任意字母都可以。常用T表示,是Type的縮寫。
泛型的實例化:
一定要在類名后面指定類型參數的值(類型)。如:
List<String> StrList = new ArrayList<String>();
iterator<Customer> iterator = customers.iterator();
T只能是類,不能用基本數據類型填充。
泛型的幾個重要使用
1.在集合中使用泛型
2.自定義泛型類
3.泛型方法
4.泛型接口
對于泛型類
1.對象實例化時不指定泛型,默認為:Object
2.泛型不同的引用不能相互賦值。
3.加入集合中的對象類型必須與指定的泛型類型一致。
4.靜態方法中不能使用類的泛型。
5.如果泛型類是一個接口或抽象類,則不可創建泛型類的對象。
6.不能在catch中使用泛型
7.從泛型類派生子類,泛型類型需具體化
自定義泛型類
1 class Person<T>{ 2 //使用T類型定義變量 3 private T info; 4 //使用T類型定義一般方法 5 public T getInfo(){ 6 return info; 7 } 8 public void setInfo(T info){ 9 this.info=info; 10 } 11 //使用T類型定義構造器 12 public Person(){} 13 public Person(T info){ 14 this.info=info; 15 } 16 //static的方法中不能聲明泛型 17 // public static void show(T t){ 18 // 19 // } 20 //try{} 21 //catch(T t){} 22 }
對于泛型方法
方法,也可以被泛型化,不管此時定義在其中的類是不是泛型化的。在泛型方法中可以定義泛型參數,此時,參數的類型就是傳入數據的類型。
泛型方法的格式:
[訪問權限]<泛型>返回類型 方法名([泛型標識 參數名稱])拋出的異常
public class DAO{
public<E> E get(int id,E e){
E result = null;
return result;
}
}
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
? for (T o : a) {
? c.add(o);
? }? }
?
public static void main(String[] args) {
? Object[] ao = new Object[100];
? Collection<Object> co = new ArrayList<Object>();
? fromArrayToCollection(ao, co);
?
? String[] sa = new String[20];
? Collection<String> cs = new ArrayList<>();
? fromArrayToCollection(sa, cs);
?
? Collection<Double> cd = new ArrayList<>();
? // 下面代碼中T是Double類,但sa是String類型,編譯錯誤。
? // fromArrayToCollection(sa, cd);
? // 下面代碼中T是Object類型,sa是String類型,可以賦值成功。
? fromArrayToCollection(sa, co);? }
泛型和繼承的關系
如果B是A的一個子類型(子類或者子接口),而G是具有有泛型聲明的類或接口,G<B>并不是G<A>的子類型!
比如:String是Object的子類,單List<String>并不是List<Object>的子類
通配符
1.使用類型通配符:?
比如:List<?>,Map<?,?>
List<?>是List<String>、List<Object>等各種泛型List的父類。
2.讀取List<?>的對象list中的元素時,永遠是安全的,因為不管list的真實類型是什么,它包含的都是Object。
3.寫入list中的元素時,不行。因為我們不知道c的元素類型,我們不能向其中添加對象。
唯一的例外是null,它是所有類型的成員。
將任意元素加入到其中不是類型安全的:
Collection<?> c=new ArrayList<String>();
c.add(new Object());//編譯時錯誤
因為我們不知道c的元素類型,我們不能向其中添加對象
add方法有類型參數E作為集合的元素類型。我們傳給add的任何參數都必須是一個未知類型的子類。因為我們不知道那是聲明類型,所以我們無法傳遞任何東西進去。
唯一的例外是null,它是所有類型的成員。
另一方面,我們可以調用get()方法并使用其返回值。返回值是一個未知的類型,但是我們知道,它總是一個Object
有限制的通配符
<?>
允許所有泛型的引用調用
舉例:
<? extends Number>???? (無窮小 , Number]
只允許泛型為Number及Number子類的引用調用
?
<? super Number>????? [Number , 無窮大)
只允許泛型為Number及Number父類的引用調用
?
<? extends Comparable>
只允許泛型為實現Comparable接口的實現類的引用調用
?