Java:Generic Erasure如何工作

时间:2012-03-24 20:37:19

标签: java arrays generics type-erasure

  

场景A.java -----------擦除后--------> M.class

     

场景B.java -----------擦除后--------> M.class

那么为什么A是非法的并且B是合法的,因为它们在擦除后几乎具有相同的M.

在删除之前的场景A:

 class ArrayList<V> {
 private V[] backingArray;
         public ArrayList() {
             backingArray = new V[DEFAULT_SIZE]; // illegal
           }
 }

删除后的情景A:

 class ArrayList<V> {   
   private Object[] backingArray;   
      public ArrayList() {
      backingArray = new Object[DEFAULT_SIZE]; // this is not useful   
   } 
}

实际上Object [Default_Size]很有用〜 擦除前的情景B:

class ArrayList<V> {
  private V[] backingArray;
  public ArrayList() {
    backingArray = (V[]) new Object[DEFAULT_SIZE]; 
  }
}

删除后的情景B:

class ArrayList<V> {
  private Object[] backingArray;
  public ArrayList() {
    backingArray = (Object[]) new Object[DEFAULT_SIZE]; 
  }
}

1 个答案:

答案 0 :(得分:6)

方案A非法的原因是Java的协变数组通过擦除实现。这样:

Object[] foo = new String[4];
foo[0] = new Object();

会在运行时引发ArrayStoreException,因为foo指的是知道它是String[]的数组实例(即使它是通过变量foo,具有编译时类型Object[])。所以这个:

new V[4]

是非法的,因为运行时不知道要创建什么类型的数组实例。