我阅读了很多关于 Object 和 Cloneable Interface 的 clone() 方法的线程,但我找不到我的问题的合法答案。长话短说:
我发现 Object 有一个方法 clone() 可以“神奇地”克隆你的对象。但是你不能在不实现 Cloneable Interface 的情况下使用该方法,因为该接口允许 Object 使用 clone() 方法。那么他们为什么这样做呢?为什么不应该从一开始就可以克隆每个对象?
Cloneable 对于一些可变数据是有意义的。
这没有意义
一些编码风格建议将新的可变数据对象保持在最低限度。Cloneable 并不适合所有情况,如果您将所有对象都设为 Cloneable,您将无法彻底关闭它。
注意:有许多项目避免在任何地方使用 Cloneable。
因为如果每个对象(包括用户自定义类的对象)都可以通过使用clone
方法克隆,那么它可能会导致被克隆的原始对象的无意突变,因为clone
它提供了原始对象的浅拷贝。例如:
class MyClass
{
private int val;
public void setVal(int i)
{
this.val = i;
}
public int getVal()
{
return this.val;
}
public static void main(String st[]) throws Exception
{
ArrayList<MyClass> ar = new ArrayList<MyClass>();
MyClass mc = new MyClass();
mc.setVal(50);
ar.add(mc);
ArrayList<MyClass> copy =(ArrayList) ar.clone();//Since ArrayList is cloneable
copy.get(0).setVal(10);
System.out.print(ar.get(0).getVal());//it shows 10 instead of 50!!
}
}
因此我们看到克隆可能会导致被复制的原始对象的内部状态不一致。因此,为了避免这种情况,程序员在定义类时会考虑他/她是否希望克隆该类的对象。
克隆意味着创建对象的新副本,并且不会像赋值运算符那样共享内存位置。
例子
MyObject obj1 = new MyObject();
obj2 = obj1;
在这里,在这种情况下,您对 obj1 所做的任何更改都将反映在 obj2 中,反之亦然,因为 obj2 保存了 obj1 的内存位置。
但如果您不希望在 obj1 中看到对 obj2 所做的更改,或者在 obj2 中看到对 obj1 所做的任何更改,那么您执行克隆。在这种情况下,两个对象将具有不同的内存位置。