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

时间:2019-06-22 14:09:17

标签: java generic-programming generic-list

我知道不允许创建数组通用数组,因为数组需要在运行时知道其类型,但是由于通用在运行时会擦除其类型信息,因此无法创建通用数组。 但是它如何允许通用数组声明如下:

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

2 个答案:

答案 0 :(得分:1)

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
  • 您的第一个示例是编译时间评估,以确保适当的时间 打字。简单地说,该数组可能包含E类型的东西。
  • 您的第二个示例需要在运行时在E已执行的情况下执行 已经被删除。无法创建类型为E的数组,因为E不再可用。

允许通用数组声明可确保在编译时匹配适当的类型。

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

它允许以下示例:

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

然后您可以将列表或数组中的值分配给T类型的某个变量,而无需获取类强制转换异常或不必进行instanceof测试。

答案 1 :(得分:0)

如果E是当前类的正式泛型,则可以:

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

但是您不能这样做:

E[] e = new E[10];

但是声明E[] e变量还是有道理的。

因为没有人阻止您从知道数组真实类型的客户端评估数组:

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

并将其用作:

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

或者,您也可以传递数组的类以从客户端实例化:

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

因此,您看到声明E[] array并不是那么无助。