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

4
如果被克隆的 Object 类中包含非原始数据类型,例如另一个类的 Object,则对该对象进行的更改会反映在两个对象中(即原始对象和克隆的对象)?而对原始数据类型进行的更改仅反映在克隆的对象中,为什么呢?
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);
    }
}

4
因为克隆并不是深度克隆。 - Andy Turner
谷歌一下:Java中的深拷贝与浅拷贝 - UkFLSUI
1个回答

3
Java的clone()方法只创建一个浅拷贝,这意味着原始数据类型字段将复制它们的值,但对象类型字段将复制它们的引用。在您的示例中,这会导致两个对象“共享”一个Best对象。
为了实现深拷贝,即创建一个新对象而不是引用现有对象,您需要在重写的clone()方法中创建一个新的Best对象,并手动分配值或使Best也可克隆。我更喜欢使Best可克隆,因为更改Best类的字段不需要更改Test类的clone()方法。尝试以这种方式创建深拷贝时最重要的事情是,您必须一直克隆到仅包含原始数据字段,这并不总是合理/可能。如果情况如此,则只需手动分配值。
使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;   
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接