Java泛型

jopen 10年前發布 | 26K 次閱讀 Java Java開發

一 定義
泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。這種參數類型可以用在類、接口和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。

二 泛型作用
1)提高的代碼的復用性
2)泛型提供了類型檢查,減少了數據的類型轉換
3)保證了類型安全
例如下面這段代碼,會拋出ClassCastException異常

List list = new ArrayList();
list.add("abc");
list.add(new Integer(1));//可以通過編譯
for (Object object : list) {
    System.out.println((String)object);//拋出ClassCastException異常
}

使用泛型后則避免這種情況發生

List<String> list = new ArrayList<String>();
list.add("abc");
//list.add(new Integer(1));//編譯器類型檢查,不能通過編譯
for (String string : list) {
    System.out.println(string);//無需強制類型轉換
}

注意,不能在泛型中添加其它類型

public static <T> void fromArrayToCollection(T[] a,Collection<T> c){
    for (T t : a) {
        c.add(t);
        //c.add(new Object());  //編譯錯誤
    }
}

三 泛型邊界
作用:
1)確保泛型類型只能是某一部分類型,比如操作數據的時候,你會希望是Number或其子類類型
2)可以調用該類型方法,Java為了兼容前面的版本,泛型的實現是通過類型擦除來實現的,使用泛型的時候加上的類型參數,會被編譯器在編譯的時候去掉,在生成的Java字節代碼中是不包含泛型中的類型信息的。這個過程就稱為類型擦除。如在代碼中定義的List<Object>和List<String>等類型,在編譯之后都會變成List。System.out.println(new ArrayList<String>().getClass()==new ArrayList<Integer>().getClass());//true
對于如下方法,如果傳入一個String,想在test方法中里面調用String.equals方法則無法實現

public void test(T t){
    t.equals("");//error
}

加入邊界后,則可以:

class Hasf{
    public void f();
}
public <T extends Hasf> void test(T t){
    t.f();
}

注意:邊界也可以有多個,用class D <T extends A&B&C>{} 限制范圍中最多有一個類。如果用一個類作為限定,它必須是限定列表中的第一個。

四 泛型繼承
看如下方法

public void test(List<Object> list);

如果傳入一個List<String>,則編譯會出錯。盡管String是Object的子類,但List<String>不是List<Object>的子類,也就是說,無論類A與類B是否存在關聯,MyClass<A>與MyClass<B>都沒有任何關聯。
但因為List<E> extends Collection<E>,
所以List<Object>則是Collection<Object>的子類型,ArrayList<Object>就是List<Object>的子類型,所以test中可以傳入ArrayList<Object>

五 通配符
在聲明泛型(給泛型賦值)時,既可以指定一個具體的類型,如List<String>就聲明了具體的類型是String;也可以用通配符?來表示未知類型,如List<?>就聲明了List中包含的元素類型是未知的。?號解決java泛型中List<String> 不是List<Object>子類的問題

public static void doTest(List<Parent>list){}
public static void doTest1(List<? extends Parent> list){
    //不能為list添加非null數據
}
class Parent{}
class Child extends Parent{
}
public static void main(String[] args){
    List <Parent>parentList=new ArrayList<Parent>();
    List <Child>childList=new ArrayList<Child>();
    doTest1(parentList);
    doTest1(childList); // 如果是doTest(childList);的話,這里編譯錯誤 
}
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!