(一). 泛型java
1.1 介紹數組
泛型是JDK5.0新增長的一個特性,泛型的本質是參數化類型,即所操做的數據類型都被指定爲一個參數。這種類型參數能夠用在類、接口、和方法的建立中,分別稱爲泛型類、泛型接口、泛型方法。Java語言引入泛型的好處是安全簡單。安全
1.2 認識泛型測試
在JDK5.0以前,沒有泛型的狀況下,經過對類型Object的引用來實現參數的"任意化",但"任意化"帶來的缺點是須要顯示的強制類型轉換,此種轉換要求開發者對實際參數類型預知的狀況下進行的。對於強制類型轉換錯誤的狀況,編譯器可能不會提示錯誤,但在運行的時候會出現異常,這是一個安全隱患。this
1.3 泛型的優點spa
使用泛型的優點在於編譯期間檢查類型,捕捉類型不匹配錯誤,而且全部的轉換都是自動和隱式多的,提升代碼複用率。code
(二). 泛型的使用 對象
2.1 泛型定義blog
實例化泛型類的語法結構以下:繼承
1 classname<type-param-list> obj = new classname<type-param-list> (cons-arg-list);
泛型定義一般使用一個惟一的大寫字母表示一個類型參數。
2.2 代碼演示
1 //建立泛型類 2 public class Generic <T> { 3 private T ob;//定義泛型成員變量 4 public Generic(T ob){ 5 this.ob = ob; 6 } 7 public T getOb(){ 8 return ob; 9 } 10 public void setOb(T ob){ 11 this.ob = ob; 12 } 13 public void showType(){ 14 System.out.println("實際類型是:" + ob.getClass().getName()); 15 } 16 }
接下來建立類:
1 //建立測試類,用於解釋泛型的使用方法 2 public class GenericDemo { 3 public static void main(String[] args) { 4 //定義泛型類Genneric的一個Integer版本 5 Generic<Integer> intOb = new Generic<Integer>(88); 6 intOb.showType(); 7 int i = intOb.getOb(); 8 System.out.println("value=" + i); 9 System.out.println("---------------------------------"); 10 //定義泛型類Genneric的一個String版本 11 Generic<String> strOb = new Generic<String>("Hello"); 12 strOb.showType(); 13 String s = strOb.getOb(); 14 System.out.println("value=" + s); 15 } 16 }
運行結果:
1 實際類型是:java.lang.Integer 2 value=88 3 --------------------------------- 4 實際類型是:java.lang.String 5 value=Hello
2.3 理解泛型需注意3點
(三). 有界類型
3.1 介紹
在有些時候須要對類型參數的取值進行必定程度的限制,以使數據具備可操做性。爲了處理這種狀況,Java提供了有界類型。在指定類型參數時可使用extends關鍵字限制此類型參數表明的類必須繼承自指定父類或父類自己。好比建立一個類:public class BoundGeneric<T extends Number>{},BoundGeneric類的定義中,使用extends關鍵字將T的類型限制爲Number類及其子類。
3.2 注意
在使用extends(如:T extends someClass)聲明的泛型類進行實例化時,運行傳遞的類型參數是:若是someClass是類,能夠傳遞someClass自己及其子類,若是someClass是接口,則能夠傳遞實現接口的類。
3.3 通配符
通配符由」?「來表示,表明一個未知類型。
例如:public static void func(Generic <?> T){}或者結合有界類型使用
public static void func(Generic <? extends Number> T)
(四). 泛型的侷限
4.1 泛型的侷限性
其實Java並無真正的實現泛型,是編譯器在編譯的時候在字節碼上了作手腳(成爲擦除),這種實現理念形成java泛型自己有不少漏洞,侷限性很大。其中大多數限制性是由類型擦除引發的。
1 public class GenericException <T> extends Exception{ 2 //泛型類沒法繼承Throwable,非法 3 }
不能在catch子句中使用類型參數,以下面的方法將不能編譯:
1 public static <T extends Throwable> void doWork(Class<T> t){ 2 try { 3 } catch (T e) {//不能捕獲類型參數異常 4 } 5 }
可是,在異常聲明中可使用類型參數。下面這個是合法的:
1 public static <T extends Throwable> void doWork(T t) throws T { 2 try { 3 } catch (Throwable realCause) {//不能捕獲類型參數異常 4 throw t; 5 } 6 }
1 public class Gen<T>{ 2 //靜態變量不能引用類型參數 3 static T ob; 4 //靜態方法不能引用類型參數 5 static T getOb(){ 6 return ob; 7 } 8 }
儘管不能在靜態變量或靜態方法中引用類型參數,但能夠聲明靜態泛型方法。
(五). 技巧
當方法靜態時,不能訪問類上定義的泛型,若是靜態方法使用泛型,只能將泛型定義在方法上,注意放置位置:public static <Y> void method(Y obj)
? extends E :接收E類型或者E的子類對象((對於自己來講是)上限)
? super E :接收E類型或者E的父類型(下限)
在集合存元素時,通常使用上限,由於這樣取出都是按照上限類型來運算,不會出現安全隱患。
何時使用下限呢?
一般對集合中的元素進行取出操做時,能夠用下限。