在单例对象中克隆某些东西
Cloning something inside a singleton object
也许我只是停电了,但我找不到可行的方法来解决我的问题。
我有一个 Class A
的单例对象,其中包含一个 ArrayList<Item>
。在 Class C
中,我需要 ArrayList<Item>
的特定 Item
(克隆它)。虽然 ArrayList<Item>
应该保持不变,但我需要对 Class C
中的 Item
进行一些修改。我尝试像这样在 Class Item
中实现 Cloneable:
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();
}
}
}
问题是 Item item
在单例对象中也被修改了。
问: 我是不是用错了方法?我怎样才能得到想要的行为?
实际情况是,克隆不是 "deep" 克隆,您仍然引用相同的内容:
private ArrayList<String> mSize = new ArrayList<>();
在你体内 克隆对象。如果它是一个没有 Collection 属性的克隆对象,它就可以正常工作。
Apache Commons Lang 有 SerializationUtils#clone,它在对象图中的所有 类 实现 Serializable 接口时执行深度复制。
item = (Item) SerializationUtils.clone(A.getInstance().getItems().get(0));
这里:
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
那基本上就是一个"no op"。它 而不是 神奇地将列表内容复制到新列表中。仅作记录:对于 any 方法,override 确实没有意义,只能调用 super 方法实现。那么你也可以:只是不要重写那个方法。
因此,要么使用不同的机制,要么真的覆盖该方法,使用自定义内容创建新列表。否则,您的克隆和原始 Item 对象在 相同 列表实例上运行。
也许我只是停电了,但我找不到可行的方法来解决我的问题。
我有一个 Class A
的单例对象,其中包含一个 ArrayList<Item>
。在 Class C
中,我需要 ArrayList<Item>
的特定 Item
(克隆它)。虽然 ArrayList<Item>
应该保持不变,但我需要对 Class C
中的 Item
进行一些修改。我尝试像这样在 Class Item
中实现 Cloneable:
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();
}
}
}
问题是 Item item
在单例对象中也被修改了。
问: 我是不是用错了方法?我怎样才能得到想要的行为?
实际情况是,克隆不是 "deep" 克隆,您仍然引用相同的内容:
private ArrayList<String> mSize = new ArrayList<>();
在你体内 克隆对象。如果它是一个没有 Collection 属性的克隆对象,它就可以正常工作。
Apache Commons Lang 有 SerializationUtils#clone,它在对象图中的所有 类 实现 Serializable 接口时执行深度复制。
item = (Item) SerializationUtils.clone(A.getInstance().getItems().get(0));
这里:
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
那基本上就是一个"no op"。它 而不是 神奇地将列表内容复制到新列表中。仅作记录:对于 any 方法,override 确实没有意义,只能调用 super 方法实现。那么你也可以:只是不要重写那个方法。
因此,要么使用不同的机制,要么真的覆盖该方法,使用自定义内容创建新列表。否则,您的克隆和原始 Item 对象在 相同 列表实例上运行。