4

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

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

4

3 回答 3

4

Cloneable 对于一些可变数据是有意义的。

这没有意义

  • 不可变数据
  • 您可能需要浅拷贝或深拷贝。
  • 表示资源的对象,例如线程、套接字、GUI 组件
  • 单例和枚举类型
  • 只应复制数据以避免创建新对象的可变状态。

一些编码风格建议将新的可变数据对象保持在最低限度。Cloneable 并不适合所有情况,如果您将所有对象都设为 Cloneable,您将无法彻底关闭它。

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

于 2013-05-01T09:29:58.670 回答
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!!
  }
}

因此我们看到克隆可能会导致被复制的原始对象的内部状态不一致。因此,为了避免这种情况,程序员在定义类时会考虑他/她是否希望克隆该类的对象。

于 2013-05-01T09:34:10.410 回答
-2

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

例子

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

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

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

于 2013-05-01T09:32:48.067 回答