编译时我得到了未经检查的表达式错误,发现有问题的行是
ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone();
我正在尝试执行对象的深层复制,因此我以上述方式克隆了对象和数组列表的属性。我该如何修复此警告?
@SuppressWarnings("unchecked")
,但这只是隐藏问题(我没想到)这样做的正确方法是什么?
答案 0 :(得分:4)
如果你的元素是整数,那么执行“深层复制”确实不是问题,因为你没有理由需要复制一个Integer对象。只需使用new ArrayList<Integer>(this.items)
。
但是作为参考,clone()和ArrayList复制构造函数都不会执行深层复制。这只是因为你的元素类型不需要深度复制才能满足你的需求。
答案 1 :(得分:1)
您可以使用new ArrayList<Integer>(this.items)
获得相同的行为。无论哪种方式,它都是浅副本。
答案 2 :(得分:1)
整数是不可变的,所以如果你做一个深层复制并不重要。
使用java.util中的Collections实用程序类:
import java.util.Collections;
...
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size());
Collections.copy(items, this.items);
答案 3 :(得分:0)
由于将泛型引入Java API时需要向后兼容性,因此在某些情况下无法使用强制转换和@SuppressWarnings("unchecked")
。
另外,请参阅here,了解谨慎使用clone()
用法的原因:它执行浅拷贝,对于大写字母来说很好,但对于对象很危险。
答案 4 :(得分:0)
您已经说过您正在尝试进行深层复制,但正如here所述,我怀疑您是否能够使用clone()
来做到这一点。所以,就像其他海报所说的那样,使用clone()
是一种更危险的方法,而你却无法获得你一直在寻找的深层拷贝。
答案 5 :(得分:0)
正如其他人所指出的,克隆ArrayList
并不克隆其元素。如果你想要对内容进行深层复制,那就有一个巧妙的技巧:序列化和反序列化数组。 (这是有效的,因为ArrayList
和Integer
都实现了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
的费用。