------<a target="blank">java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------
(一). 泛型
1.1 介紹
泛型是JDK5.0新增加的一個特性,泛型的本質是參數化類型,即所操作的數據類型都被指定為一個參數。這種類型參數可以用在類、接口、和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。Java語言引入泛型的好處是安全簡單。
1.2 認識泛型
在JDK5.0之前,沒有泛型的情況下,通過對類型Object的引用來實現參數的"任意化",但"任意化"帶來的缺點是需要顯示的強制類型轉換,此種轉換要求開發者對實際參數類型預知的情況下進行的。對于強制類型轉換錯誤的情況,編譯器可能不會提示錯誤,但在運行的時候會出現異常,這是一個安全隱患。
1.3 泛型的優勢
使用泛型的優勢在于編譯期間檢查類型,捕捉類型不匹配錯誤,并且所有的轉換都是自動和隱式多的,提高代碼復用率。
(二). 泛型的使用
2.1 泛型定義
實例化泛型類的語法結構如下:
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.Integer2 value=883 ---------------------------------4 實際類型是:java.lang.String5 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的父類型(下限)
在集合存元素時,一般使用上限,因為這樣取出都是按照上限類型來運算,不會出現安全隱患。
什么時候使用下限呢?
通常對集合中的元素進行取出操作時,可以用下限。
新聞熱點
疑難解答