为什么`Stream.collect`类型安全且`Stream.toArray(IntFunction <a []>)`不是?</a []>

时间:2014-05-21 17:14:04

标签: java types java-8 java-stream

考虑以下代码片段

String strings[] = {"test"};
final List<String> collect = java.util.Arrays.stream(strings).collect(java.util.stream.Collectors.toList());
final Double[] array = java.util.Arrays.stream(strings).toArray(Double[]::new);

为什么Java可以保证collect-case中的正确类型(将collect的泛型类型更改为例如Double导致编译时错误),但不在数组的情况下(编译正常,尽管apply(int)Double[]::new代码为Double[],而不是Object[],但如果上面使用不正确,会引发ArrayStoreException

如果在不更改IntFunction调用中的给定toArray的情况下更改流的类型,生成编译时错误的最佳方法是什么?

1 个答案:

答案 0 :(得分:12)

方法Stream::toArray的签名如下所示。请注意,类型参数TA完全不相关。

public interface Stream<T> {
    <A> A[] toArray(IntFunction<A[]> generator);
}

ReferencePipeline.java的来源中,您可以找到以下评论:

  

由于AU无关(无法声明AU的上限)   没有静态类型检查。   因此,使用原始类型并假设A == U而不是传播AU的分隔   整个代码库。   永远不会检查U的运行时类型是否与运行时类型A[]的组件类型相等。   当元素存储在A[]中时,将执行运行时检查,因此如果A不是a   U的超级类型将被抛出。