Java 类型擦除和数组

Sud*_*mar 2 java arrays generics type-erasure

oracle 文档说泛型是使用一种技术调用类型擦除在 java 中实现的,这就是它的工作原理。

  1. 如果类型参数无界,则将泛型类型中的所有类型参数替换为其边界或对象。因此,生成的字节码仅包含普通的类、接口和方法。
  2. 如有必要,请插入类型转换以保持类型安全。
  3. 生成桥接方法以保留扩展泛型类型中的多态性。

因此,如果我有一个通用类,请说 Container 如下:

class Container<T>{
T initialValue;
List<T> valueList=new ArrayList<T>();
public List<T> getValueList(){
  return valueList;
}

}
Run Code Online (Sandbox Code Playgroud)

经过类型擦除处理后,它的等效类看起来像这样:

class Container{
    Object initialValue;
    List valueList=new ArrayList();
    public List getValueList(){
      return valueList;
    }

    }
Run Code Online (Sandbox Code Playgroud)

如果这里有错请指正

同样,如果将上面的类修改如下

class Container<T>{
    T initialValue;
    List<T> valueList=new ArrayList<T>();
    T[] arrayValue;
    public Container(T[] array){
       arrayValue=array;
     }
    public List<T> getValueList(){
      return valueList;
    }

    }
Run Code Online (Sandbox Code Playgroud)

这不等于吗???

class Container{
    Object initialValue;
    List valueList=new ArrayList();
    Object[] arrayValue;
    public Container(Object[] array){
       arrayValue=array;
     }
    public List getValueList(){
      return valueList;
    }

    }
Run Code Online (Sandbox Code Playgroud)

如果这是真的那么我也应该这样: T[] arrayValue=new T[10];//Compile time error; 因为上面的语句会被转换成

Object[] arrayValue=new Object[10];
Run Code Online (Sandbox Code Playgroud)

需要清楚了解 Java 中数组的类型擦除如何工作?

Hoo*_*pje 6

您无法创建通用数组。原因是数组早于 Java 的泛型,并且数组不使用类型擦除。例如,anInteger[]和 aString[]在运行时确实具有不同的类型。如果你写new T[],编译器不知道它需要创建什么样的数组。

您可以通过执行以下操作来创建假通用数组:

T[] array = (T[]) new Object[10];
Run Code Online (Sandbox Code Playgroud)

但你要记住,你真正创建的是一个Object数组,而不是一个T数组。在运行时,可以将非T实例放入其中,因此仅当数组是类的私有字段且从未传递给其他对象时才执行此操作,以便您可以准确控制将哪些对象放入数组中。

如果您有一个Class<T>实例(所谓的类型标记),您可以使用它Array.newInstance来创建具有正确运行时类型的新数组:

T[] array = (T[]) Array.newInstance(typeToken, 10); 
Run Code Online (Sandbox Code Playgroud)

  • 不,类型擦除不适用于数组。在运行时,“List&lt;Integer&gt;”和“List&lt;String&gt;”具有相同的类型,即“List”,但“Integer[]”和“String[]”具有不同的类型。 (3认同)