首页 文章

Java类型擦除和数组

提问于
浏览
1

oracle doc说Generics是使用技术调用类型擦除在java中实现的,这就是它的工作原理 .

  • 如果类型参数是无界的,则用泛化或对象替换泛型类型中的所有类型参数 . 因此,生成的字节码仅包含普通的类,接口和方法 .

  • 如有必要,插入类型转换以保持类型安全 .

  • 生成桥接方法以保留扩展泛型类型中的多态性 .

所以,如果我有一个Generic类,请说Container如下:

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

}

在类型擦除处理后,它的等效类看起来像:

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

    }

如果这里错了,请纠正我

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

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;
    }

    }

这不等于???

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

    }

如果这是真的那么我也应该这样: T[] arrayValue=new T[10]; //编译时错误;因为上面的陈述会被转换成

Object[] arrayValue=new Object[10];

需要明确类型擦除如何在Java中使用数组?

1 回答

  • 2

    您无法创建通用数组 . 原因是数组早于Java的泛型,而数组不使用类型擦除 . 因此,例如, Integer[]String[] 在运行时确实具有不同的类型 . 如果编写 new T[] ,编译器不知道需要创建哪种类型的数组 .

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

    T[] array = (T[]) new Object[10];
    

    但你必须记住,你真的创建了一个 Object 数组,而不是 T 数组 . 在运行时,可以在其中放置非 T 实例,因此只有在数组是类的私有字段时才会执行此操作,该字段永远不会传递给其他对象,因此您可以准确控制在阵列 .

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

    T[] array = (T[]) Array.newInstance(typeToken, 10);
    

相关问题