初識泛型擦除

多次聽到泛型擦除也看過不少的博客解釋,但始終都是看的時候覺得挺有道理一轉眼就忘的一乾二淨,歸根結底是沒有自己的認識。所以我今天翻看了ArrayList的實現源碼來真真正的認識一下泛型擦除。
我們都用過ArraryList類,都知道他是一個容器類,並且從javase5之後是一個類型安全的容器類(我們再使用他的時候必須指定這個泛型的具體類型,然後在使用他的過程中也只能向這個容器中添加這個類型的對象,最後使用get方法獲得的也一定是這個類型的對象),具體使用如下所示:

package test;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Apple> list = new ArrayList<Apple>(); //"<>"中指定泛型的具體類型爲Apple
        list.add(new Apple());   //添加Apple類型的對象,成功
        //list.add(new Orrange());   //添加Orrange類型的對象,報錯
    }
    static class Apple {

    }
    static class Orrange {

    }
}

按照這個思路思考的話,那ArrayList中保存的就應該是Apple類型的對象,而不是其他的類型,但事實上卻不是這樣。在ArrayList中Apple的對象卻是以Object類型進行保存(進行了向上轉型),並不是以我們指定的Apple類型進行保存。來看源碼:

在這裏插入圖片描述
在這裏插入圖片描述
可以看到elementData數組的類型爲Object類型,add方法直接將添加的對象添加到了elementData數組。這種對象保存到容器中失去了原來的類型統一轉型爲Object類型的現象就叫泛型擦除。

現在我們就有疑問了,既然統一擦除了原來的類型那又怎麼保證get方法得到的對象不是Object類型而是對象的原來類型呢?接下來我們看get方法的源碼:
在這裏插入圖片描述
可以看到在每次返回元素的時候都是用了"(E)"進行強轉。這樣我們get到的結果就是原來的類型了。

添加數據的時候上轉爲Object類型,查找數據的時候有強轉爲原來的類型,這樣轉過來轉過去的有什麼意義呢?爲什麼直接創建一個E類型的數組而多此一舉的創建Object類型的數組呢?原因是泛型是不能創建數組的

public class Apple<E> {
        E []e = {};   //報錯
        E []ee = new E[10];   //報錯
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章