【发布时间】: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 数组”。