2012-01-18 35 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复制字节的开销。

相关问题