1. 程式人生 > >Java泛型的擦除特性小記

Java泛型的擦除特性小記

ArrayList<A> arrayList = new ArrayList<>();
arrayList.add(new A());

ArrayList arrayList2 = arrayList;

ArrayList<B> arrayList3 = arrayList2;
arrayList3.add(new B());

上面這段程式碼會向同一個ArrayList中新增兩種不同的型別(A,B沒有任何關係,是完全獨立的兩個類)。你也許會說正常沒人這麼寫程式碼,但真正的程式碼可能會和他差異很大,最終出現問題的原因卻和這裡一致。

由於擦除的存在,如果你可以拿到ArrayList的泛型資訊,arrayList,arrayList2,arrayList3會給你不同的答案。下面再舉一個例子:

ArrayList arrayList = new ArrayList<Integer>();

上面這段程式碼,如果你獲取到arrayList的泛型,你會發現,它不是Integer。

小結

由於“擦除”的存在,泛型類不存在向上轉型,向下轉型。特別的,當你“向上轉型”到通用型別(如ArrayList<Integer> -> ArrayList)時,泛型會丟失,此時你會失去ArrayList中儲存資料的型別的資訊(此時ArrayList會丟失所有基於泛型的特性,它看起來就是一個沒有泛型的ArrayList)。此時你可以“向下轉型”到任何型別。

泛型只和宣告點有關,沒有實際型別一說。(普通的物件,當它被new出來,它的實際型別是確定的,無論你怎麼轉型,它本質上就是new時的型別,但泛型物件不是,泛型物件的泛型永遠和宣告點同類型,而不在乎new時的型別)