簡體   English   中英

為什么Java ArrayList使用每個元素的轉換而不是每個數組的轉換?

[英]Why does Java ArrayList use per-element casting instead of per-array casting?

Java的ArrayList<T> (可能還有很多其他類)中發生的事情是內部Object[] array = new Object[n]; ,寫入T對象。 每當從中讀取一個元素時,一個強制轉換return (T) array[i]; 已經完成了。 所以,每次閱讀時都要施展。

我想知道為什么這樣做。 對我來說,似乎他們只是做了不必要的演員表。 創建一個T[] array = (T[]) new Object[n];是不是更合乎邏輯,也更快一點T[] array = (T[]) new Object[n]; 然后只return array[i]; 沒有演員? 這只是每個數組創建一個強制轉換,通常遠遠小於讀取次數。

為什么他們的方法是首選的? 我不明白為什么我的想法不是更嚴格?

它比這更復雜:泛型以字節代碼擦除, T[]的擦除是Object[] 同樣, get()的返回值變為Object 為了保持類型系統的完整性,在實際使用類時插入檢查的強制轉換,即

Integer i = list.get(0);

將被刪除

Integer i = (Integer) list.get(0);

既然如此,ArrayList中的任何類型檢查都是多余的。 但它確實不重要,因為(T)(T[])都是未經檢查的強制轉換,並且不會產生運行時開銷。

可以編寫一個檢查過的ArrayList:

T[] array = Array.newInstance(tClass, n);

這樣可以防止堆污染 ,但代價是冗余類型檢查(你無法抑制調用代碼中的合成轉換)。 它還需要調用者為ArrayList提供元素類型的類對象,這會使其api變得混亂並使其在通用代碼中更難使用。

編輯:為什么禁止創建通用數組?

一個問題是檢查數組,而未檢查泛型。 那是:

Object[] array = new String[1];
array[0] = 1; // throws ArrayStoreException

ArrayList list = new ArrayList<String>();
list.add(1); // causes heap pollution

因此,陣列的組件類型很重要。 我假設這就是Java語言的設計者要求我們明確使用哪種組件類型的原因。

每當從中讀取一個元素時,一個強制轉換return (T) array[i]; 已經完成了。 所以,每次閱讀時都要施展。

Generic是編譯時檢查。 在運行時,使用類型T extends代替。 在這種情況下, T隱式extends Object因此您在運行時所擁有的是有效的。

return (Object) array[i];

要么

return array[i];

創建一個不是更合乎邏輯,也更快一點

T[] array = (T[]) new Object[n]

並不是的。 在運行時再次成為

Object[] array = (Object[]) new Object[n];

要么

Object[] array = new Object[n];

你真正釣魚的是

T[] array = new T[n];

除了這不編譯,主要是因為T在運行時不知道。

你能做的是

private final Class<T> tClass; // must be passed in the constructor

T[] array = (T[]) Array.newInstance(tClass, n);

只有這樣,數組實際上才是預期的類型。 這可以使讀取速度更快,但代價是寫入。 主要的好處是快速檢查失敗,即你會阻止一個集合被破壞,而不是等到你發現它被破壞后拋出異常。

我認為更多的是代碼風格而不是性能或類型安全(因為支持數組是私有的)

java 5 ArrayList實現方式與您對E[]數組的建議方式相同。 如果您查看源代碼,您會看到它包含7個(E [])強制轉換。 從java 6開始, ArrayList更改為使用Object[]數組,該數組僅導致3(E)個轉換。

數組也是對象。 這里T[] array = (T[]) new Object[n]你只投射(T [])對象類型而不是數組中的元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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