泛型的簡單介紹和使用

一、泛型出現的背景

早期Java是使用Object來代表任意類型的,這樣使用會出現兩個問題:

  • Collection、Map集合對元素的類型無法做限制。本來我的Collection集合想裝載的只能是Dog對象,但是外邊把Cat對象存儲到集合中,是沒有任何語法錯誤的。
  • 把對象扔進集合中,集合是不知道元素的類型是什麼的,僅僅知道是Object。因此在get()的時候,返回的是Object,還需要強制轉換。

爲了解決這兩個問題,泛型應運而生,我們通過泛型可以限制某個類(常應用在集合類中)中元素的類型,並且get時不需要進行強轉。

二、自定義一個簡單的泛型類

public class GenericTest<T> {

    private T genericValue;

    public T getGenericValue() {
        return genericValue;
    }

    public void setGenericValue(T genericValue) {
        this.genericValue = genericValue;
    }

    public static void main(String[] args) {
        GenericTest<String> stringGenericTest = new GenericTest<>();
//     1、只能set String類型的值
        stringGenericTest.setGenericValue("123");
//     2、存放整形的值會報錯
//        stringGenericTest.setGenericValue(123);
//     3、取出的值不需要強轉
        String stringValue = stringGenericTest.getGenericValue();
        System.out.println(stringValue);
//     4、且必須用String來接收,不然會報錯
//        Integer integer = stringGenericTest.getGenericValue();
    }

}

三、注意事項

  • 什麼是類型擦除?
    Java中的泛型是在編譯器這個層次來實現的,生成的Java字節碼中是不包含泛型的類型信息的。而泛型的類型參數,會在編譯器在編譯的時候去掉,這個過程就稱爲類型擦除。
    如:
    第五條:在代碼中定義的ArrayList和ArrayList類型,在編譯後都會變成List。
    第六條:通過反射可以在Integer集合中的Integer類型被擦除後存放字符串
//      5、泛型的類型擦除證明:兩個ArrayList編譯後的類型是相同的
        ArrayList<String> stringArrayList = new ArrayList<>();
        stringArrayList.add("123");
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        integerArrayList.add(123);
        System.out.println(stringArrayList.getClass() == integerArrayList.getClass());
//      6、類型擦除的證明:通過反射可以跳過編譯階段的類型檢測將字符串存到整形集合中
        integerArrayList.getClass().getMethod("add",Object.class).invoke(integerArrayList,"我是字符串");
        System.out.println(integerArrayList.get(1));

更多細節參考大神博文:泛型的類型擦除

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章