为什么`Stream.collect`类型安全,而`Stream.toArray(IntFunction< A []>)`不是? [英] Why is `Stream.collect` type-safe and `Stream.toArray(IntFunction<A[]>)` is not?
问题描述
考虑以下代码片段
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 []
,而不是对象[]
,但抛出 ArrayStoreException
如果上面使用不正确的话?)
Why can Java guarantee the correct type in the collect-case (changing the generic type of collect to e.g. Double leads to a compile time error), but not in the array case (compiles fine, despite apply(int)
of Double[]::new
gives a Double[]
, not an Object[]
, but throws ArrayStoreException
if used incorrectly as above)?
如果我改变了,那么产生编译时错误的最佳方法是什么?流的类型没有更改 toArray
调用中的给定 IntFunction
?
What would be the best way to generate a compile time error in case I change the type of the stream without changing the given IntFunction
in the toArray
call?
推荐答案
方法 Stream :: toArray
的签名如下所示。请注意,类型参数 T
和 A
完全不相关。
The signature of the method Stream::toArray
looks as follows. Please note that the type parameters T
and A
are completely unrelated.
public interface Stream<T> {
<A> A[] toArray(IntFunction<A[]> generator);
}
在 ReferencePipeline.java ,你可以找到以下评论:
In the source of ReferencePipeline.java, you can find the following comment:
由于
A
与<$ c $无关c> U (无法声明A
是U
的上限
将不会进行静态类型检查。
因此使用原始类型并假设A == U
而不是传播A
和<的分离整个代码库中code> U
。
永远不会检查U
的运行时类型是否与运行时类型A [] $ c $的组件类型相等C>。
当元素存储在A []
中时,将执行运行时检查,因此如果A
不是将抛出
超类型U
ArrayStoreException
。
Since
A
has no relation toU
(not possible to declare thatA
is an upper bound ofU
) there will be no static type checking. Therefore use a raw type and assumeA == U
rather than propagating the separation ofA
andU
throughout the code-base. The runtime type ofU
is never checked for equality with the component type of the runtime type ofA[]
. Runtime checking will be performed when an element is stored inA[]
, thus ifA
is not a super type ofU
anArrayStoreException
will be thrown.
这篇关于为什么`Stream.collect`类型安全,而`Stream.toArray(IntFunction< A []>)`不是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!