2012-01-18 73 views
1

我編譯時未檢查的表達錯誤,發現有問題的行是Java的不安全或未經檢查的表達式:克隆一個ArrayList

ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone(); 

我想,所以我克隆執行我的對象的深層副本以上述方式對象和數組列表的屬性。我如何解決這個警告?

  • 我可以使用@SuppressWarnings("unchecked")但這僅僅是隱瞞問題(儘管我希望沒有)
  • 如果我手動克隆通過各種元素,它的循環會比較慢,我認爲

請告訴我正確的做法呢?

回答

4

如果您的元素是整數,執行「深度複製」確實不是問題,因爲沒有理由需要複製Integer對象。只需使用new ArrayList<Integer>(this.items)即可。

但是作爲參考,clone()和ArrayList拷貝構造函數都不會做深度拷貝。這只是因爲你的元素類型不需要深度複製,這可以滿足你的需求。

1

您可以通過new ArrayList<Integer>(this.items)獲得相同的行爲。無論哪種方式,但這是一個副本。

API

+0

當然,沒有必要對Integer對象進行深層複製。 – 2012-01-18 04:29:54

0

因爲當他們推出泛型的Java API所需的向後兼容的,有圍繞在某些情況下使用鑄造和@SuppressWarnings("unchecked")沒有辦法。

此外,請參見here爲什麼clone()的使用應該小心使用:它做一個淺拷貝,這對主動性來說很好,但對於對象來說是危險的。

+0

你可以把原語放在'ArrayLists'中?我以爲你只能放置物體,而且最多隻能裝入原始物體。 – blahman 2012-01-18 04:25:49

+0

@blahman問題是當克隆時原始字段沒問題,但是對象字段(如'ArrayList items')是麻煩來源。 – 2012-01-18 04:33:54

+0

哦......哎呀。完全錯過了。對不起,遇事。我的不好^^'另外,謝謝@TedHopp =) – blahman 2012-01-18 04:38:39

0

你說過你正在嘗試做一個深層複製,但正如討論here,我懷疑你可以使用clone()做到這一點。所以,就像其他海報所說的那樣,使用clone()是一種更危險的方法,您將無法獲得您一直在尋找的深層副本。

1

整數是不可變的,因此如果您進行深度複製或不復制,則無關緊要。

使用集合實用工具類java.util中:

import java.util.Collections; 
... 
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size()); 
Collections.copy(items, this.items); 
+0

'Arrays.copyOf'不返回'ArrayList'。 – 2012-01-18 04:32:06

+0

糟糕,意思是Collections.copy,而不是Arrays.copyOf。 – marathon 2012-01-18 04:37:04

0

正如其他人所指出的那樣,克隆ArrayList並不克隆它的元素。如果你想做一個內容的深層副本,有一個巧妙的技巧:序列化和反序列化數組。 (這是可行的,因爲ArrayListInteger都執行Serializable。)但是,這並沒有擺脫禁止未經檢查的轉換警告的需要。

// Write the object out to a byte array 
ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutputStream out = new ObjectOutputStream(bos); 
out.writeObject(this.items); 
byte[] bytes = bos.toByteArray(); 

// Retrieve an input stream from the byte array and read 
// a copy of the object back in. 
ObjectInputStream in = new ObjectInputStream(
    new ByteArrayInputStream(bytes)); 
ArrayList<Integer> items = (ArrayList<Integer>) in.readObject(); 

如果您的整個對象可以被聲明爲Serializable,那麼可以使用它來代替克隆操作來進行深度複製。此外,請參閱this article,以避免從ByteArrayOutputStream複製字節的開銷。

相關問題