簡體   English   中英

為什么Java的Collection <E> .toArray()返回一個Object []而不是一個E []?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM