使用 Object 类的 clone() 方法克隆对象



如果正在克隆对象的类包含非原始数据类型,例如另一个类的对象,那么在此对象中所做的更改会反映在两个对象中(即原始对象和克隆对象(?虽然在基元数据类型中所做的更改仅反映在克隆对象中,但为什么?

import static java.lang.System.*;
class Best
{
int x;
int y;
}
class Test implements Cloneable
{
int a;
int b;
Best bt = new Best();
public Object clone()throws CloneNotSupportedException
{
return super.clone();   
}
}
public class Check 
{
public static void main(String [] args) throws CloneNotSupportedException
{
Test t1 = new Test();
t1.a=20;
t1.b=30;
t1.bt.x = 300;
t1.bt.y = 200;
Test t2 = (Test)t1.clone();
t2.a=50; //change reflects only in cloned object
t2.bt.x = 500; //change reflects in both original and cloned object
out.println(t1.a+" "+t1.b+" "+t1.bt.x+" "+t1.bt.y);
out.println(t2.a+" "+t2.b+" "+t2.bt.x+" "+t2.bt.y);
}
}

Java clone(( 方法只创建一个浅拷贝,这意味着原始数据类型字段复制其值,但对象类型字段复制其引用。在您的示例中,这会导致两个对象"共享"一个 Best 对象。

要完成深层复制,其中创建新对象而不是引用现有对象,您需要在覆盖的clone((方法中创建一个新的Best对象,并手动分配值或使Best也可克隆。我更喜欢使最佳可克隆,因为更改最佳类的字段不需要更改测试类的克隆((方法。尝试以这种方式创建深层副本时,最重要的事情是您必须始终向下克隆,直到您只到达原始数据字段,这并不总是合理/可能的。如果是这种情况,只需手动分配值即可。

使最佳克隆:

class Best implements Cloneable
{
int x;
int y;
public Object clone() throws CloneNotSupportedException
{
return super.clone();   
}
}
class Test implements Cloneable
{
int a;
int b;
Best bt = new Best();
public Object clone()throws CloneNotSupportedException
{
Test t = (Test) super.clone();
t.bt = (Best) this.bt.clone();
return t;   
}
}

手动分配值:

class Best
{
int x;
int y;
}
class Test implements Cloneable
{
int a;
int b;
Best bt = new Best();
public Object clone()throws CloneNotSupportedException
{
Test t = (Test) super.clone();
t.bt.x = this.bt.x;
t.bt.y = this.bt.y;
return t;   
}
}

最新更新