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

前段时间在上国外某教授的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.java
import 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)

...

}

猜你喜欢

转载自blog.csdn.net/shendezhuti/article/details/78324334