在单例对象内克隆某些东西

时间:2019-06-05 09:37:03

标签: java singleton

也许我只是停电了,但我找不到解决问题的可行方法。

我有一个包含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(); } } } 也被单例对象修改了。

问: 我是否对此采取了错误的方法?如何获得所需的行为?

2 个答案:

答案 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具有Seri​​alizationUtils#clone,当对象图中的所有类都实现Serializable接口时,它将执行深层复制。

item = (Item) SerializationUtils.clone(A.getInstance().getItems().get(0));