由Cannot create a generic array of ArrayList引出的學習--Java範型

最近在用Java寫某個程序時希望寫出一個包括ArrayList<xx>的數組

自己定義如下:

ArrayList<edge>[] edges = new ArrayList<edge>()[10];

然後編譯器報錯如下:

Cannot create a generic array of ArrayList<edge>;


在C++裏可以這樣比較方便的定義:  vector<edge> a[100];

在Java裏報錯,查詢了一下,見已經有人在stackoverflow上問了這個問題,鏈接如下:

http://stackoverflow.com/questions/4549192/create-an-array-of-arrayliststring-elements

上面的鏈接講的多是解決(代替)方法,具體這樣設計的原因還要自己繼續深究。


一、出現這個問題的原因

     正如IDE報錯的信息所述:無法創建範型數組,底層的數組類型只能是Object的。

     類型擦除:

     簡單來說,就是JVM將泛型存儲的東西都視爲Object,

     即ArrayList<Integer>.class = ArrayList<String>.class = ArrayList<Object>.class

     所以你如果定義了泛型數組,在使用的時候就很可能發生"貓插入狗列表"的事件

     那我們接着探討,爲什麼會引入類型擦除,<<Thinking in Java>>中介紹了這其中的歷史原因,因爲在JavaSE1.5之前是沒有泛型的,

     於是爲了與之前版本類庫的融合(不重寫之前的類庫),所以目前採用了類型擦除這種方法.

     

二、解決的方法

     1、很簡單,不用泛型。再額外定義一個class T, T裏面包括一個ArrayList成員變量,藉由T的public方法add向ArrayList裏添加元素

     2、方法一是對我這個程序的解決方法,對於Java泛型更通用的方法,class XX <T> { } 來說,

         <<Thinking In Java>>上面講了四種解決方案,具體如下:

        http://blog.csdn.net/eric_sunah/article/details/7262486

                 沒有任何方式可以推翻底層的數組類型,它只能是Object[]

                 所以作者講的前三種方式涉及Object與其它類型之間的轉型都可能會拋出異常或無法編譯

                 所以應該採用上面鏈接所描述的第四種方法,將類型標記<T>傳遞到構造器中,以便從擦除中恢復                

 

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