聲明:原創作品,轉載時請注明文章來自SAP師太技術博客( 博/客/園www.cnblogs.com):m.survivalescaperooms.com/jiangzhengjun,并以超鏈接形式標明文章原始出處,否則將追究法律責任!原文鏈接:http://m.survivalescaperooms.com/jiangzhengjun/p/4255654.html 第五章 泛型23、 請不要在新代碼中使用原生態類型聲明中具有一個或者多個類型參數的類或者接口,就是泛型類或者泛型接口。泛型類和接口統稱為泛型。
每種泛型可以定義一種參數化的類型,格式為:先是類或者接口的名稱,接著用尖括號(<>)把對應于泛型的類型參數的實際類型參數列表括起來。
每個泛型都定義一個原生態類型,即不帶任何實際類型參數的泛型名稱,也是沒有泛型之前的類型。
泛型能將運行時期的錯誤提前到編譯時期檢測。
如果使用原生態類型,就失掉了泛型在安全性和表述性方面的所有優勢。既然不應該使用原生態類型,為什么Java設計還要允許使用它們呢?這是為了提供兼容性,要兼容以前沒有使用泛型的Java代碼。
原生態類型List和參數化的類型List<Object>之間到底有什么區別呢?不嚴格地說,前者逃避了泛型檢查,后者則明確告知編譯器,它能夠持有任意類型的對象。泛型有子類型化的規則:List<String>是原生態類型List的一個子類型,而不是參數化類型List<Object>的子類型(見25條)。因此,如果用不用像List這樣的原生態類型,就會失掉類型安全性,但是如果使用像List<Object>這樣的參數化類型,則不會。
在無限制通配類型Set<?>和原生態類型Set之間有什么區別呢?由于可以將任何元素放進使用原生態類型的集合中,因此很容易破壞該集合的類型約束條件;但不能將任何元素(除了null之外)放到Collection<?>中。
“不要在新代碼中使用原生態類型”,這條規則有兩個例外,這是因為“泛型信息在運行時就會被擦除”。在獲取類信息中必須使用原生態類型(數組類型和基本類型也算原生態類型),規范不允許使用參數化類型。換句話說:List.class,String[].class和int.class都是合法,但是List<String>.class和List<?>.class都是不合法的。這條規則的第二個例外與instanceof操作符有關,由于泛型信息在運行時已被擦除,因此在參數化類型而不是無限制通配符類型(如List<?>)上使用instanceof操作符是非法的,用無限制通配符類型代替原生態類型,對instanceof操作的行為不產生任何影響。在這種情況下,尖括號<>和問號?就顯得多余了。下面是利用泛型來使用instanceof操作符的首先方法:
if(o instanceof set){
Set<?> m = (Set<?>)o;
// ...
}
注意,一旦確定這個o是個Set,就必須將它轉換成通配類型Set<?>,則不是轉換成原生態類型Set,否則Set會引起編譯時警告。
總之,使用原生態類型會在運行時導致異常,因此不要在新代碼中使用。原生態類型只為了與引入泛型之前的遺留代碼進行兼容和互用而提供的。另外Set<Object>是個參數化類型,表示可以包括任何對象類型的一個集合;Set<?>則是一個通配符類型,表示只能包含某種未知對象類型的一個集合;Set則是個原生態類型,它脫離了泛型系統。前兩者是安全的,最后一種不安全。
術語介紹:
原生態類型:List
參數化的類型:List<String>
泛型:List<E>
有限制類型參數:List<E extends Number>
形式類型參數:E
無限制通配符類型:List<?>
有限制通配符類型:List<? extends Number>
遞歸類型限制:List <T extends Comparable<T>>
泛型方法:static<E> List<E> asList(E[] a)
24、 消除非受檢警告用泛型編程時,會遇到許多編譯器警告:非受檢強制轉換警告、非受檢方法調用警告、非受檢普通數組創建警告,以及非受檢轉換警告。
要盡可能地消除每一個非受檢警告。如果消除了所有警告,就可以確保代碼是類型安全的。
新聞熱點
疑難解答