2014-05-21 9 views
12

考慮下面的代碼片段爲什麼`Stream.collect`類型安全並且`Stream.toArray(IntFunction <A[]>)`不是?

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[]::newapply(int)給出Double[],而不是Object[],但如果使用上述不正確的方式會拋出ArrayStoreException)?

如果在不更改toArray調用中給定IntFunction的情況下更改流的類型,那麼生成編譯時錯誤的最佳方法是什麼?

回答

9

方法Stream::toArray的簽名如下所示。請注意,類型參數TA完全無關。

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

ReferencePipeline.java源,你可以找到以下注釋:

由於A沒有任何關係U(不可能宣佈A是一個上限的U) 會有不是靜態類型檢查。 因此,使用原始類型並假設爲A == U,而不是在整個代碼庫中傳播分隔AU 。 從不檢查運行時類型U與運行類型A[]的組件類型是否相等。 當元素存儲在A[]中時將執行運行時檢查,因此如果A不是 超類型U將會拋出ArrayStoreException

+0

這是「超級T」會有幫助的情況之一嗎?如果是這樣,那麼很有趣的是,他們還沒有解決這個問題,因爲它對於我來說似乎是一個「必須」,如果它在這樣一個API中。 – skiwi

+0

那麼,正如你指出的那樣,我正在尋找它們完全不相關的原因。把一個''看起來很容易。因此,我期望在Stream接口的實現中會遇到一些問題或者類似的問題。 – muued

相關問題