也许我只是停电了,但我找不到解决问题的可行方法。
我有一个包含Class A
的{{1}}单例对象。在ArrayList<Item>
中,我需要Class C
中的特定Item
(将其克隆)。尽管ArrayList<Item>
应该保持不变,但我需要对ArrayList<Item>
中的Item
进行一些修改。我尝试像这样在Class C
中实现Cloneable:
Class Item
然后我想像这样获得public class Item implements Cloneable {
private ArrayList<String> mSize = new ArrayList<>();
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void modifySomething() {
mSize.clear();
}
}
:
Item
问题是class C {
void foo() {
Item item = null;
try {
item = (Item) A.getInstance().getItems().get(0).clone();
item.modifySomething();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
也被单例对象修改了。
问: 我是否对此采取了错误的方法?如何获得所需的行为?
答案 0 :(得分:3)
这里:
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
这基本上是“无操作”。它不会不神奇地将列表内容复制到新列表中。仅作记录:对于 any 方法,覆盖确实没有意义,但是仅调用super方法实现。然后,您也可以:只是不重写该方法。
因此,可以使用其他机制,也可以真的用自定义内容覆盖该方法,以创建新的List。否则,您的克隆对象和原始Item对象将在相同列表实例上运行。
答案 1 :(得分:2)
发生的事情是,该克隆不是“深层”克隆,您仍然引用相同的对象:
private ArrayList<String> mSize = new ArrayList<>();
您内部的克隆对象。如果它是一个没有Collection属性的克隆对象,则对您来说很好。
Apache Commons Lang具有SerializationUtils#clone,当对象图中的所有类都实现Serializable接口时,它将执行深层复制。
item = (Item) SerializationUtils.clone(A.getInstance().getItems().get(0));