为什么一个对象不应该是可复制的?

时间:2013-05-01 09:19:56

标签: java interface clone cloneable

我阅读了很多关于Object和Cloneable Interface的clone()方法的线程,但我找不到我的问题的合理答案。 长话短说:

我想到的是Object有一个方法clone(),可以“神奇地”克隆你的对象。但是如果不实现Cloneable Interface,则无法使用该方法,因为此接口允许Object使用clone()方法。那他们为什么这样做呢?为什么不能从一开始就克隆每个对象?

3 个答案:

答案 0 :(得分:3)

Cloneable对某些可变数据有意义。

没有意义
  • 不可变数据
  • 您可能需要浅色或深色副本。
  • 表示线程,套接字,GUI组件等资源的对象
  • 单身和枚举类型
  • 可变状态,其中只应复制数据以避免创建新对象。

某些编码样式建议将新的可变数据对象保持在最低限度。 Cloneable并不适合所有情况,如果你让所有对象Cloneable,你将无法完全关闭它。

注意:有许多项目都避免在任何地方使用Cloneable。

答案 1 :(得分:1)

因为如果只使用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!!
  }
}

因此我们看到克隆可能导致被复制的原始对象的内部状态不一致。因此,为了避免这种情况,程序员在定义类时是否需要克隆该类的对象是否普遍存在。

答案 2 :(得分:-2)

克隆意味着创建对象的新副本,并且不会像赋值运算符那样共享内存位置。

示例

         MyObject obj1 = new MyObject();
         obj2 = obj1;

在这种情况下,在这种情况下,您对obj1所做的任何更改都将反映在obj2中,反之亦然,因为obj2保存了obj1的内存位置。

但是如果你不想要,可以在obj1中看到obj2中所做的更改,或者在obj2中看到obj1中所做的任何更改,那么就执行克隆。在这种情况下,两个对象将具有不同的内存位置。