为什么在java中不能创建泛型数组

来源:互联网 发布:php 开源社区系统 编辑:程序博客网 时间:2024/06/11 21:47

前段时间在上国外某教授的algorithm课程,提到在java中不能创建泛型数组,课后也有这个思考题,自己百思不得其解,于是翻开了《think in java》这本书,在书的第15章,写到。这是由于擦除机制。(尽管通读了第15章,小白作者还是有很多地方不明白,如果读者能明白,望不吝赐教)

public class ErasedTypeEquicalence {    public static void main (Sring args[]){        Class c1=new Arraylist().getClass();        Class c2=new Arraylist().getClass();    System.out.println(c1==c2);    }        /*ourput:    *true    */}

在这个小代码中我们看到结果也许有有点迷糊,为什么返回的true,其实arraylist<String>和arraylist<Integer>很容易被认为是不同的类型,不同的类型在行为方面肯定不同。然而上面的程序认为他们是相同的类型。

在下面,书上又介绍了另一端比较长的例子。

//: generics/LostInformation.javaimport java.util.*;class Frob {}class Fnorkle {}class Quark {}class Particle {}public class LostInformation {  public static void main(String[] args) {    List list = new ArrayList();    Map map = new HashMap();    Quark quark = new Quark();    Particle p = new Particle();    System.out.println(Arrays.toString(      list.getClass().getTypeParameters()));    System.out.println(Arrays.toString(      map.getClass().getTypeParameters()));    System.out.println(Arrays.toString(      quark.getClass().getTypeParameters()));    System.out.println(Arrays.toString(      p.getClass().getTypeParameters()));  }} /* Output:[E][K, V][Q][POSITION, MOMENTUM]*///:~

Class.getTypeParemeters() 将 "返回一个TypeVarivable的对象数组表示有泛型声明所声明的类型参数",好像暗示我们可能发现参数类型的信息,但是从输出我们可以看到,能够发现的只是用作参数占位符的标识符,这,并没有什么卵用。

书上提到了:这是一个残酷的现实:在泛型代码内部,无法获得任何有关泛型参数类型的信息。

泛型是通过擦除实现的,这意味着当你使用泛型时,任何具体的类型信息都被擦除了,你唯一所知道的就是你在使用一个对象。之前说的arraylist<String>和arraylist<Integer>在运行时会被擦除成“原生”的类型,即list。

书上提到了 泛型不是java语言出现就有的组成成分,所以为了减少擦除的混淆,我们要意识到,擦除是java语言实现泛型的一种折中,这种折中会让我们痛苦。。由于擦除的存在,泛型在java中的使用不像它原来设想的那么有用,尽管还是存在用处。

擦除的核心动机是它使得泛化的客户端可以用非泛化的类库,反之亦然,这经常被称为“迁移兼容性”。

擦除的代价是显著的,泛型不能用于显式地引用运行时类型的操作之中,例如转型、instanceof操作和new表达式。因为所有关于参数的类型信息都已经丢失了。

因此像  public class Eraesd<T>{

....

T [] arrary =new T[size]     ;//这样的代码会出现error  (won't compile)

...

}

原创粉丝点击