码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2014-11-14 22:52:29      阅读:273      评论:0      收藏:0      [点我收藏+]

标签: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范型

标签:java   泛型   擦除   算法      

原文地址:http://blog.csdn.net/cgf1993/article/details/41089137

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!