为什么'Stream.collect'是类型安全的,而'Stream.toArray(IntFunction<A[]>)“不是?

2022-09-02 22:20:30

请考虑以下代码片段

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可以保证集合大小写中的正确类型(将集合的泛型类型更改为例如Double会导致编译时错误),但在数组情况下却不能保证(编译良好,尽管给出了一个,而不是一个,但如果如上所述使用不正确,则会抛出)?apply(int)Double[]::newDouble[]Object[]ArrayStoreException

如果我更改了流的类型而不更改调用中的给定类型,那么生成编译时错误的最佳方法是什么?IntFunctiontoArray


答案 1

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

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

ReferencePipeline.java 的源代码中,您可以找到以下注释:

由于与(不可能声明是的上限)没有关系,因此不会进行静态类型检查。因此,使用原始类型并假定而不是在整个代码库中分离和传播。从不检查 运行时类型的 运行时类型 是否与 运行时类型的组件类型 相等。当元素存储在 中时,将执行运行时检查,因此如果不是将抛出的超类型。AUAUA == UAUUA[]A[]AUArrayStoreException


答案 2