最近在用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>傳遞到構造器中,以便從擦除中恢復