简体   繁体   English

Java为什么允许通用数组声明?

[英]why does Java allow generic array declaration?

I know that array generic array creation is not allowed because arrays need to know their type at run-time but since generic erase their type information at run-time it is not possible to create generic array. 我知道不允许创建数组通用数组,因为数组需要在运行时知道其类型,但是由于通用在运行时会擦除其类型信息,因此无法创建通用数组。 But how come it allows generic array declaration as follow : 但是它如何允许通用数组声明如下:

private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling
private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling
  • Your first example was compile time evaluation to ensure proper typing. 您的第一个示例是编译时间评估,以确保正确键入。 Simply says that this array may contain something of type E. 简单地说,该数组可能包含E类型的东西。
  • Your second example would need to be executed at run time when E has already been erased. 您的第二个示例将需要在运行时已擦除E的情况下执行。 Can't create an array of type E because E is no longer available. 无法创建类型为E的数组,因为E不再可用。

Allowing generic array declarations ensures that appropriate types are matched at compile time. 允许通用数组声明可确保在编译时匹配适当的类型。

      Integer[] ints1 = null;
      String[] str1 = null;

      // both requires cast or it won't compile
      Integer[] ints = (Integer[])doSomething1(ints1);
      String[] str = (String[])doSomething1(str1);

      //but that could result in a runtime error if miscast.
      //That type of error might not appear for a long time

      // Generic method caters to all array types.
      // no casting required.
      ints = doSomething2(ints1);
      str = doSomething2(str1);

   }

   public static Object[] doSomething1(Object[] array) {
      return array;
   }

   public static <T> T[] doSomething2(T[] array) {
      return array;
   }

It allows examples such as the following: 它允许如下示例:

public <T> void copy(List<T> list, T[] array) {
   for (T e : array) {
      list.add(e);
   }
}

You could then assign a value from either the list or the array to some variable of type T without getting a class cast exception or without having to to an instanceof test. 然后,您可以将列表或数组中的值分配给T类型的某个变量,而无需获取类强制转换异常或不必进行instanceof测试。

If E is a formal generic of the current class, yes you can do that : 如果E是当前类的正式泛型,则可以这样做:

List<E> e = new ArrayList<E>();

but you cannot do that : 但您不能这样做:

E[] e = new E[10];

But declaring the E[] e variable makes sense all the same. 但是声明E[] e变量是完全一样的。

because no one prevents you from valuing the array from the client side that knows the real type of the array : 因为没有人阻止您从知道数组真实类型的客户端评估数组:

Foo<E> class{        
    private E[] array;
    Foo(E[] array) {
        this.array = array;
    }
}

And to use it as : 并将其用作:

Foo<String> foo = new Foo<>(new String[] { "a", "b" });

Or as alternative you could also pass the class of the array to instantiate from the client side : 或者,您也可以传递数组的类以从客户端实例化:

Foo<String> foo = new Foo<>(String.class);

So you see that declaring E[] array is not so helpless. 因此,您看到声明E[] array并不是那么无助。

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

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