1. 程式人生 > >Cannot create a generic array of ArrayList

Cannot create a generic array of ArrayList

最近在用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上問了這個問題,連結如下:

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

一、出現這個問題的原因

     正如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>>上面講了四種解決方案,具體如下:

                 沒有任何方式可以推翻底層的陣列型別,它只能是Object[]

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

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