我们无法创建泛型类型的数组,这是一个众所周知的事实,所以我不打算在这里提供对JLS的正式引用。但我们可以声明这样的数组如下:
static <E> void reduce() {
List<Integer>[] arr; //compiles fine
E[] avv; //compiles fine
avv = new E[10]; //doesn't compile
arr = new List<Integer>[10]; //doesn't compile
}
有人知道这种声明的原因吗?
答案 0 :(得分:2)
首先,我认为你的意思是
avv = new E[2]; //doesn't compile
arr = new List<Integer>[2]; //doesn't compile
在你方法的最后两行。您必须在创建新数组时指定数组的大小。但是,代码仍然无法编译。
阵列早于泛型。自Java的第一个版本以来,存在数组,而泛型仅在1.5版本中添加。为了打破旧代码,Java设计者决定在运行时擦除泛型类型:在运行时,类型参数被其上限替换。在您的情况下,在运行时,E
与Object
相同。目前还不知道E
是哪种类型。
这是一个问题,因为,数组元素类型在运行时不会被删除。 Integer[]
和String[]
是不同的类型,即使在运行时也是如此。如果编写new E[2]
,Java运行时不知道它必须创建哪种类型的数组。它可以是String[]
或Integer[]
,也可以是任何其他数组类型。因此,您无法使用通用元素创建新数组。
仍允许使用具有泛型元素的数组作为类型,主要是为了在方法参数中使用它们:
<E> E doSomething(E[] param) { ... }
实际数组是在程序的另一部分中创建的,其类型是已知的。您可以使用
调用此方法String result = doSomething(new String[2]);
例如。
答案 1 :(得分:1)
它允许您将泛型类型的数组作为方法参数传递。
例如:
public class Foo<T>
{
public void bar (T[] arr) {}
}
...
Foo<String> foo = new Foo<String>();
String[] arr = {"aa","bb");
foo.bar (arr);
如果不允许T[]
,则方法签名必须为public void bar (Object[] arr)
,并且编译器允许您将任何类型的数组传递给该方法。