Why is `Stream.collect` type-safe and `Stream.toArray(IntFunction<A[]>)` is not?

时间秒杀一切 提交于 2019-12-18 12:15:44

问题


Consider the following code fragment

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);

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)?

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?


回答1:


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);
}

In the source of ReferencePipeline.java, you can find the following comment:

Since A has no relation to U (not possible to declare that A is an upper bound of U) there will be no static type checking. Therefore use a raw type and assume A == U rather than propagating the separation of A and U throughout the code-base. The runtime type of U is never checked for equality with the component type of the runtime type of A[]. Runtime checking will be performed when an element is stored in A[], thus if A is not a super type of U an ArrayStoreException will be thrown.



来源:https://stackoverflow.com/questions/23789829/why-is-stream-collect-type-safe-and-stream-toarrayintfunctiona-is-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!