[英]Why does Java's Collection<E>.toArray() return an Object[] rather than an E[]?
在Java泛型之前, Collection.toArray()
無法知道開發人員期望的數組類型(特別是對於空集合)。 據我所知,這是成語collection.toArray(new E[0])
背后的主要理由.toArray collection.toArray(new E[0])
。
使用泛型, Collection<E>.toArray()
只能返回一個充滿E
和/或其特化實例的數組。 我想知道為什么返回類型仍然是Object[]
而不是E[]
。 在我看來,返回E[]
而不是Object[]
不應該破壞現有的代碼。
請參閱: Collection.toArray()
, Collection.toArray(T[])
和相關主題java:(String [])List.toArray()給出ClassCastException
這是一個非常好的問題。 答案是仿制葯也被稱為“擦除”。 它不僅僅是一個名字。 由泛型編碼的信息僅在編譯時使用,然后被刪除。 所以,JVM甚至不知道這個泛型類型E
,所以它不能創建數組E[]
。
其他方法toArray(T[] a)
在運行時從參數接收有關類型的信息。 這就是這個方法的原型是<T> T[] toArray(T[] a)
:它得到類型為T的數組並且可以返回類型為T的數組。該類型作為參數傳遞。
“類型擦除”只是部分解釋: Collection
和它的toArray()
方法都沒有在運行時有關E
任何信息。
這也是因為向后兼容性, Collection.toArray()
仍然必須返回Object[]
。 在Java 1.5之前,無法知道集合的泛型類型,因此這是唯一合理的API設計。
@Lukas,關於:“new E []”
正如您可能預期的那樣,新的E [0]引發了引用錯誤。 我找到的解決方法是:
final E [] returnArray = (E [])events.toArray(new Event [events.size()]);
注意,代碼位於模板類Listener <E extends Event>中。
在我的解決方法中,類型擦除既是問題也是解決方案。 轉換為(E [])是安全的,因為它的精確類型被刪除為Event []。 我看到的唯一缺點是編譯器警告“未經檢查或不安全的操作”(顯然,在這種情況下,在給定類型擦除的情況下,強制轉換)。
@Lukas,關於向后兼容性
我沒有看到向后兼容性的大問題。 使返回類型更特殊與使參數類型更特殊不同。
換句話說,到目前為止期望Collection.toArray()返回Object []的源代碼應該非常樂意接收E []。
至於字節代碼,由於類型擦除,Object []和E []無論如何都是相同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.