日期:2017/11/25
泛型的使用能夠解決處理不同類型資料時遇到的困難。泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的資料類型被指定為一個參數。這種參數類型可以用在類、接口和方法的建立中,分别稱為泛型類、泛型接口、泛型方法。 Java語言引入泛型的好處是安全簡單。
在Java SE 1.5之前,沒有泛型的情況的下,通過對類型Object的引用來實作參數的“任意化”,“任意化”帶來的缺點是要做顯式的強制類型轉換,而這種轉換是要求開發者對實際參數類型可以預知的情況下進行的。對于強制類型轉換錯誤的情況,編譯器可能不提示錯誤,在運作的時候才出現異常,這是一個安全隐患。
泛型的好處是在 編譯的時候檢查類型安全,并且所有的強制轉換都是自動和隐式的,以提高代碼的重用率。
代碼例子1:
package com.code.generic_paradigm;
//ArrayList<String> a ; ArrayList b
import java.util.ArrayList;
public class test02 {
public static void main(String[] args){
ArrayList<String> a = new ArrayList<String>();
ArrayList b = new ArrayList();
Class c1 = a.getClass();
Class c2 = b.getClass();
System.out.println(c1.getClass().getName());
System.out.println(c2.getClass().getName());
System.out.println(c1 == c2); //true
}
}
代碼例子2:
package com.code.generic_paradigm;
class FX<T>{
private T ob;
public FX(T ob){
this.ob = ob ;
}
public T getob(){
return ob;
}
public void showetype(){
System.out.println("T real parttern is :"+ob.getClass().getName());
}
}
public class test01 {
public static void main(String [] args){
FX<Integer> intob = new FX<Integer>(100) ;
intob.showetype();
System.out.println("value="+intob.getob());
System.out.println("------------------");
FX<String> strob = new FX<String>("mmb");
strob.showetype();
System.out.println("value="+strob.getob());
}
}
輸出結果:
T real parttern is :java.lang.Integer
value=100
------------------
T real parttern is :java.lang.String
value=mmb
泛型的好處:
(1)類型安全。
通過知道使用泛型定義的變量的類型限制,編譯器可以更有效地提高Java程式的類型安全。
(2)消除強制類型轉換。
消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,并且減少了出錯機會。所有的強制轉換都是自動和隐式的。
(3)提高性能。
[java]
view plain
copy
- new ArrayList();
- "CSDN_SEU_Cavin ");
- 0);
[java]
view plain
copy
- new ArrayList<String>();
- "CSDN_SEU_Cavin ");
- 0);
對于上面的兩段程式,由于泛型所有工作都在編譯器中完成,javac編譯出來的位元組碼是一樣的(隻是更能確定類型安全),那麼何談性能提升呢?是因為在泛型的實作中,編譯器将強制類型轉換插入生成的位元組碼中,但是更多類型資訊可用于編譯器這一事實,為未來版本的 JVM 的優化帶來了可能。
注意事項
(1)泛型的類型參數隻能是類類型(包括自定義類),不能是簡單類型。
(2)泛型的類型參數可以有多個。
(3)不能對确切的泛型類型使用instanceof操作。如下面的操作是非法的,編譯時會出錯。
[java]
view plain
copy
- if(ex_num instanceof FX<Number>){
- }
(4)不能建立一個确切的泛型類型的數組。
[java]
view plain
copy
- new List<String>[10]; // Not really allowed.
- Object o = lsa;
- Object[] oa = (Object[]) o;
- new ArrayList<Integer>();
- new Integer(3));
- 1] = li; // Unsound, but passes run time store check
- 1].get(0); // Run-time error: ClassCastException.
這種情況下,由于JVM泛型的擦除機制,在運作時JVM是不知道泛型資訊的,是以可以給oa[1]賦上一個ArrayList<Integer>而不會出現異常,但是在取出資料的時候卻要做一次類型轉換,是以就會出現ClassCastException,如果可以進行泛型數組的聲明,上面說的這種情況在編譯期将不會出現任何的警告和錯誤,隻有在運作時才會出錯。
下面采用通配符的方式是被允許的:
[java]
view plain
copy
- new List<?>[10]; // OK, array of unbounded wildcard type.
- Object o = lsa;
- Object[] oa = (Object[]) o;
- new ArrayList<Integer>();
- new Integer(3));
- 1] = li; // Correct.
- 1].get(0); // OK