Java1.5中添加了泛型。沒有泛型之前,從集合中讀取的每一個對象都必須進行轉(zhuǎn)換,如果不小心添加了類型錯誤的對象,在運行時的轉(zhuǎn)換處理就會出錯。有了泛型之后,子啊編譯時就會告知是否插入了錯誤的類型
第23條 請不要在代碼中使用原生態(tài)類型
每個泛型都定義一個原生態(tài)類型(raw type),即不帶任何實際類型參數(shù)的泛型名稱。例如,與List<E>相對呀的原生態(tài)類型是List。
java為了兼容性,開發(fā)者仍然可以使用原生態(tài)類型,但這樣就失去了泛型在安全性和表達性方面的所有優(yōu)勢。
如果要使用泛型,但不確定或者不關(guān)心實際的類型參數(shù),就可以使用一個問好代替。泛型Set<E>的無限制通配符類型為Set<?>,這是最普通的參數(shù)化Set類型,可以持有任何集合。但是不能把除了null以外的任何月嚴肅放到Collection<?>中,不然編譯器會報錯。
第24條:消除非受檢警告
當遇到非受檢警告時。如果消除了所有警告,就可以確代碼是類型安全的,是一件很好的事情。這意味著不會子啊運行時出現(xiàn)ClassCastException一場,你會更加自信自己的程序可以實現(xiàn)預(yù)期的功能。
如果無法消除警告,同時可以證明引起警告的嗲嗎是類型安全的,(只有這種情況下才)可以用一個@SuppressWarnings("unchecked")注解來禁止這條警告。
永遠不要在整個類上使用SuppressWarnings,這樣做可能會掩蓋了重要的警告。
總的來說,要盡量減小SuppressWarnings的作用范圍。并用注釋把禁止該警告的原因記錄下來。
第25條:列表優(yōu)先于數(shù)組
創(chuàng)建泛型數(shù)組是非法的。
數(shù)組是協(xié)變可以具體化的,泛型是不可變且可以被擦除的。因此,數(shù)組提供了運行時的類型安全,但是沒有編譯時的類型安全,反之,對于泛型也一樣。
數(shù)組的協(xié)變性(covariant)是指:
如果類Base是類Sub的基類,那么Base[]就是Sub[]的基類。
而泛型是不可變的(invariant),List<Base>不會是List<Sub>的基類,更不會是它的子類。
數(shù)組是在運行時才去判斷數(shù)組元素的類型約束,而泛型正好相反,在運行時,泛型的類型信息是會被擦除的,只有編譯的時候才會對類型進行強化。
java泛型是編譯器泛型,是一種語法糖,生成的二進制代碼中是沒有泛型的,jvm感受不到泛型。java的泛型編譯生成二進制代碼的時候,進行了類型的擦除,放入集合的實際上是object類型,從集合中獲取對象的時候 獲取的是object類型, 然后進行了強制類型轉(zhuǎn)換,轉(zhuǎn)換成實際的類型。
第26條:優(yōu)先考慮泛型
這條主要介紹了如何寫泛型
使用泛型類比使用需要在客戶端類中轉(zhuǎn)換的類型要安全的多。也更加容易。在設(shè)計新類型的時候,要確保它們不需要轉(zhuǎn)換就可以使用,這通常意味著要把類做成是泛型的。只要時間允許,就把所有的類泛型化。這對于這些類型的新用戶來說會變得更加輕松,又不會破壞現(xiàn)有的客戶端。
第27條:優(yōu)先考慮泛型方法
泛型構(gòu)造器必須指定參數(shù)類型,而泛型方法不需要。
泛型構(gòu)造器指定參數(shù)類型的時候比較麻煩,所以推薦用靜態(tài)工廠類代替構(gòu)造器
第28條:利用有限制通配符來提升API的靈活性
第29條:優(yōu)先考慮類型安全的異構(gòu)容器
類Class在Java 1.5版本中被泛型話了。類的類型從字面上來看不再只是簡單的Class,而是Class<T>.
//類型安全的異構(gòu)兼容類型--API
public class Favorites {
public <T> void putFavorites(Class<T> type, T instance);
public <T> getFavorite(Class<T> type);
}
//類型安全的異構(gòu)兼容類型--client
public static void main(String[] args) {
Favorites f = new Favorites();
f.putFavorite(String.class, "Java");
f.putFavorite(Integer.class, 0xcafebabe);
f.puFavorite(Class.class, Favorites.class);
String favoriteString = f.getFavorite(String.class);
int favoriteInteger = f.getFavorite(Integer.Class);
Class<?> favoriteClass = f.getFavorite(Class.class);
System.out.printf("%s %x %s%n",favoriteString, favoriteInteger, favoriteClass);
}
打印出來的結(jié)果是Java cafebabe Favorites.
Class的cast方法是Java的cast操作符的動態(tài)模擬。它只檢驗它的參數(shù)是否為Class對象所表示的類型的實例。如果是,就返回參數(shù);否則就拋出ClassCastException異常。