【发布时间】:2016-01-22 05:18:21
【问题描述】:
我有下面的通用方法返回一个通用数组:
public static <T> T[] genericMethod1(List<T> input) {
T[] res = (T[]) new Object[input.size()];
int i = 0;
for (T t : input) {
res[i] = t;
i++;
}
return res;
}
public static <T> T genericMethod2(List<T> input) {
return input.get(0);
}
但后来当我尝试使用以下方法获取结果数组时:
LinkedList<Integer> list = new LinkedList<Integer>();
list.addFirst(1);
list.addFirst(1);
Integer[] i = (Integer[]) genericMethod1(list); // 1) Runtime error
Integer j = genericMethod2(list); // 2) works
对于情况 1,我总是在运行时出错:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
谁能解释为什么以及如何正确返回泛型数组?谢谢。
以下是我的理解,如有错误请指正。
正如 Tim 提到的,类型擦除发生在编译时,所以在字节码中,每个 T 对象只是类型 Object,同时,编译器会“正确地”添加从 Object 到 T 的类型转换。
假设 T 是一个 Integer,其中 T 被声明,它是 Object。对于它被引用的地方,它是(隐式)类型转换为 T。
除非声明了 T[] 数组,它是 Object[],并且在引用数组的地方,它仍然是 Object[]。不会发生对 T[] 的隐式强制转换。
【问题讨论】:
-
泛型在运行时不保留类型。
-
这里总结一下,类型擦除删除了类型,所以如果要返回特定类型的泛型数组,则需要传入该类型。