`

数组和泛型

    博客分类:
  • j2se
阅读更多

1.数组提供了运行时的类型安全,但是没有编译时的类型安全检测;而泛型提供了编译时类型安全检查,运行时进行类型擦除。

  如下代码:

Object[] longArray = new Long[1];
longArray[0]="I am test";

 编译可以通过,但是运行的时候会抛出:java.lang.ArrayStoreException异常。

 

而如下代码:

List<Object> list = new ArrayList<Long>(); //Type mismatch: cannot convert 
                                  //from ArrayList<Long> to List<Object>
list.add("I am test");

 编译时就通不过,因为泛型不支持子类化。

 

2.由于1的根本区别,因此数组和泛型不能很好的混合使用。

因此创建泛型数组(new List<E>[]),创建参数化类型数组(new List<String>[]),创建类型参数数组(new E())都是非法的。

 

3.题外话

像E,List<E>,List<String>这样的类型应该称作”不可具体化类型(non-reifiable)"。不可具体化类型可形象的理解为:其运行时表示法包含的信息比它编译时表示法包含的信息更少的类型。唯一可具体化的参数化类型是无限制的通配符类型,如List<?>和Map<?,?>。虽然不常用,但是创建无限制通配符类型数组是合法的。

 

4.补充

由于每次调用可变参数都会创建一个数组来存放可变的参数。如果这个数组的元素类型是不可具体化的,就会得到一个警告。对于这个警告的处理除了@SuppressWarning把它禁止之外,就是避免在API中混合使用泛型与可变参数。

 

最后当你获得一个创建泛型数组错误时,最好的解决办法就是优先使用集合类型List<E>或者Object[],而不是数组类型E[]。

 

 参考文档:http://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics