【发布时间】:2014-12-27 02:35:43
【问题描述】:
当我从事一个涉及 Java 8 新流的项目时,我注意到当我在流上调用 Stream#toArray() 时,它返回一个 Object[] 而不是 T[]。尽管我很惊讶,但我开始深入研究 Java 8 的源代码,但找不到任何原因他们没有将 Object[] toArray(); 实现为 T[] toArray();。这背后有什么原因吗,还是只是(不)一致性?
编辑 1: 我注意到很多人在回答中说这是不可能的,但是这段代码sn-p编译并返回了预期的结果?
import java.util.Arrays;
public class Test<R> {
private Object[] items;
public Test(R[] items) {
this.items = items;
}
public R[] toArray() {
return (R[]) items;
}
public static void main(String[] args) {
Test<Integer> integerTest = new Test<>(new Integer[]{
1, 2, 3, 4
});
System.out.println(Arrays.toString(integerTest.toArray()));
}
}
【问题讨论】:
-
它怎么知道
R?如果您希望返回特定类型,请将生成器传递给该方法。例如对于字符串数组,请执行以下操作:streamString.toArray(String[]::new) -
您不知道应该转换为哪种类型,因为在运行时 Java 不知道实际类型,因为 类型擦除(就像它在@Susei 的回答)
-
Object[]不一定是R[]。该演员在运行时肯定会失败。 -
对象没有扩展
R,所以这会抛出一个RuntimeException -
R[]的演员表应该是你的警告信号。这是一个 unchecked 强制转换,编译器会告诉你(但你可能只是忽略了这一点)。items[]不是R[]的数组,所以编译器说它不能验证这个转换是完全正确的——它不能阻止客户端转换返回的数组到Object[],然后将非 R 值放入其中,这将颠覆假设的类型安全性,即“这是一个 R 数组”。