首页 > 代码库 > 由Cannot create a generic array of ArrayList<xx>引出的学习--Java范型

由Cannot create a generic array of ArrayList<xx>引出的学习--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>传递到构造器中,以便从擦除中恢复                

 

由Cannot create a generic array of ArrayList<xx>引出的学习--Java范型