Java中为什么不允许直接创建泛型数组
在Java中,如果创建泛型数组,会出现以下编译错误, 例如List<String>[] stringLists = new List<String>[10];
会提示Error:(9, 38) java: 创建泛型数组
但是却可以创建泛型数组的引用List<String>[] stringLists = null;
并将一个普通数组的引用赋值给它。List<String>[] stringLists = new List[10];
package test; |
Java中为什么不允许直接创建泛型数组?
《Effective Java》第五章给出了一个解释:
使用泛型的作用是使得程序在编译期可以检查出与类型相关的错误,但是如果使用了泛型数组,这种能力就会受到破坏。
假如我们可以声明这样一个泛型数组(实际上是不可以的):List<String>[] stringLists = new List<String>[10];
由于在 Java 中,数组是协变(covariant)的,这意味着基类类型的数组可以接收子类类型的数组,例如:Object[] objects = stringLists;
一旦我们这样做之后,就可以通过objects向 stringLists中添加非List<String>
类型的数据。
List<Integer> intList = Arrays.asList(1); |
随后,再使用 stringList 时,stringList[0] 就会保存 intList, 而使用下面的代码,编译器不会提示错误,但运行时,就会出错。String str = stringList[0].get(0);
即使创建出来“泛型数组”以上错误也依然存在。
List<String>[] stringLists = (List<String>[])new List[10]; |
当我们创建泛型容器时:
public class Array<E> { |
解决办法:
class Array<E> { |
或者:
class Array<E> { |
泛型的出现在很大程度上是为了避免运行时出现烦人的 ClassCastException
,可是具有讽刺意味的是,泛型数组却又导致了ClassCastException
异常的出现。
解决办法:
Z[][] array=(Z[][])(Array.newInstance(Class<Z> class ,XLabel.size(),YLabel.size())); |