数组是一个具体化类型。这意味着数组的确切类型在运行时是已知的。因此,在运行时,例如,String[]
和Integer[]
之间存在差异。
这不是泛型的情况。泛型是一个编译时构造:它们用于在编译时检查类型,但在运行时确切类型不再可用。在运行时,类型参数只是Object
(或者如果类型参数具有上限,则为上限)。所以在运行时,Collection<String>
和Collection<Integer>
的类型没有区别。
现在,当您想创建一个类型参数的数组时,会出现问题。在运行时,不知道什么是T
,所以如果你编写new T[10]
,Java运行时不知道要创建什么类型的数组,String[]
或Integer[]
。这就是为什么你不能以这种方式创建一个数组。
有几个解决方法,其中没有一个是完全令人满意的。通常的解决方法是创建一个Object[]
,并把它转换到你想要的类型的数组:
T[] theArray = (T[]) new Object[size];
但是,你要记住,这是非常不安全的。如果创建的箭头的范围很小,则只应该执行此操作,以便您可以手动确保该阵列仅包含T
实例,并且永远不会将其分配给任何无法实现的实例。下面的代码演示了此问题:
public class Foo<T extends Comparable> {
T[] createArray() {
return (T[])new Object[1];
}
public static void main(String... args) {
Foo<String> foo = new Foo<>();
String[] ss = foo.createArray(); // here
}
}
标有此行抛出一个异常,因为你想投的Object[]
到String[]
!
如果你真的需要一个正确的运行时类型的数组,你需要使用反射。获取某个类型的令牌,你需要的类型(类型Class<T>
的),并使用Array.newInstance(type, cize)
创建阵列,例如:
public T[] createArray(Class<T> type, int size) {
return (T[]) Array.newInstance(type, size);
}
简单的答案是,你不能创建的项目类型从未来的数组一个类型参数。 – biziclop