简体   繁体   English

Java类型擦除和数组

[英]Java type erasure and Arrays

The oracle doc says Generics are implemented in java using a technique call type erasure and this is how it works. 甲骨文文档说,泛型使用一种技术调用类型擦除在Java中实现,这就是它的工作方式。

  1. Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. 如果类型参数不受限制,则将通用类型中的所有类型参数替换为其边界或对象。 The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods. 因此,产生的字节码仅包含普通的类,接口和方法。
  2. Insert type casts if necessary to preserve type safety. 必要时插入类型转换,以保持类型安全。
  3. Generate bridge methods to preserve polymorphism in extended generic types. 生成桥接方法以在扩展的泛型类型中保留多态。

So if I have a Generic class say Container as below: 因此,如果我有一个通用类,请说如下容器:

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

}

it's equivalent class would look like after being processed by type erasure: 经过类型擦除处理后,它的等效类看起来像:

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

    }

Correct me if a wrong here 如果这里有错请指正

Similarly, if a modify the above class as below 同样,如果修改上面的类如下

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

    }

won't be this equivalent to??? 会不会等于???

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

    }

if this is true then I should also have like this: T[] arrayValue=new T[10]; 如果是这样,那么我也应该这样: T[] arrayValue=new T[10]; //Compile time error; //编译时错误; as the above statement would get converted into 因为上面的语句将被转换为

Object[] arrayValue=new Object[10];

Need clarity on how type erasure works for Arrays in Java?? 需要澄清类型擦除如何在Java中用于数组吗?

You cannot create generic arrays. 您不能创建通用数组。 The reason is that arrays predate Java's generics, and arrays do not use type erasure. 原因是数组早于Java的泛型,并且数组不使用类型擦除。 So, for example, an Integer[] and a String[] really have different type at runtime. 因此,例如, Integer[]String[]在运行时确实具有不同的类型。 If you write new T[] , the compiler doesn't know what kind of array it needs to create. 如果编写new T[] ,则编译器将不知道需要创建哪种数组。

You can create a fake generic array by doing: 您可以通过执行以下操作来创建伪造的通用数组:

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

But you have to remember that you really created an Object array, not a T array. 但是您必须记住,您实际上创建了一个Object数组,而不是T数组。 At run-time it is possible to put non- T instances in it, so only do this if the array is a private field of your class which is never passed to other objects, so that you can control exactly what objects are put in the array. 在运行时可以在其中放置非T实例,因此只有在数组是您的类的私有字段且永远不会传递给其他对象的情况下才可以这样做,以便您可以精确地控制将哪些对象放置在对象中。阵列。

If you have a Class<T> instance (a so-called type token) you can use Array.newInstance to create a new array with the correct run-time type: 如果您具有Class<T>实例(所谓的类型令牌),则可以使用Array.newInstance创建具有正确的运行时类型的新数组:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM