【发布时间】:2018-06-10 14:21:27
【问题描述】:
我最近尝试创建一个泛型数组,发现不允许这样做:Cannot create generic array of OptionSet<T>
我决定做一个测试类,发现有一个不同的方法,结果完全相同:
public class Test {
@SuppressWarnings("unchecked")
public static final void main(String[] args) {
A<String> a = null;
A<String> b = null;
A<?>[] array1 = array(a, b); // fine, only a warning
A<?>[] array2 = new A<String>[] {a, b}; // Error: Cannot create a generic array of Test.A<String>
}
@SuppressWarnings("unchecked")
private static final <T> A<T>[] array(A<T>... a) {
return a; // fine, only a warning
}
private static final class A<T> {}
}
这是为什么呢?这两种方法的结果完全相同,但由于某种原因,一种会引发错误,另一种则可以正常工作,尽管它会发出警告。
【问题讨论】:
-
这是由于type erasure。核心点:泛型类型只存在于编译时。它们在运行时被替换为其上限。要了解如何在标准 API 中处理此类内容,您可以查看
ArrayList的实现。它使用Object[] elementData。当返回E类型的元素时(例如,ArrayList#get(int index)),它们被显式转换(并且警告通过@SuppressWarnings("unchecked")被抑制。