无法理解克隆

时间:2011-07-07 05:30:46

标签: java object cloning cloneable

我有一个简单的程序来克隆一个对象,我用Google搜索错误“线程中的异常”主“java.lang.CloneNotSupportedException:”但需要你的帮助才能理解错误,为什么我无法克隆obj1 ?

public class Test{
int a;
int b;
public Test(int a , int b){
    this.a=a;
    this.b=b;
    }
public static void main(String[]args) throws CloneNotSupportedException{
    Test obj1=new Test(2, 4);
    Test obj2=(Test) obj1.clone();
       }
 }

2 个答案:

答案 0 :(得分:4)

发生此问题是因为类Test未实现Cloneable接口。如API specs中所述,

  

如果类[..]没有实现Cloneable接口,则抛出CloneNotSupportedException。

要修复,请尝试以下方法:

public class Test implements Cloneable { 
  ...
}

由于Cloneable接口没有声明任何方法(它被称为标记接口,就像Serializable),因此无需再做任何事情。现在可以克隆Test类的实例。

但是,默认克隆机制(即Object的默认克隆机制)可能并不完全符合您的要求,您可能希望覆盖clone()方法。默认是创建一个浅层副本,也就是说,您将获得一个新的,不同的类实例,但两个实例的字段将引用相同的对象!例如:

class C1 {
  Object o;
}
class C2 implements Cloneable {
  C1 c1;
}

... main ... {
  C2 c2 = new C2();
  c2.c1 = new C1();
  c2.c1.o = new Object();
  C2 c2clone = c2.clone();
  System.out.println(c2 == c2clone); // prints false
  System.out.println(c2.c1 == c2clone.c1); // prints true
  c2.c1.o = new Object(); // modified both c2 and c2clone!!!

最后一行将修改c2和c2clone,因为它们都指向同一个c1实例。如果您希望最后一行仅修改c2,那么您必须制作我们称之为深层副本

答案 1 :(得分:2)

您必须实施Cloneable。它是一个标记界面。

你的程序应该是

    public class Test implements Cloneable{
         //rest of the program
    }