我有一个简单的程序来克隆一个对象,我用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();
}
}
答案 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
}