为什么Object类的clone()方法会提供对象的深层副本?

根据JAVA文档,super.clone()被调用时会返回该对象的浅表副本。 在下面的代码中,我有两个对象名称ID ; 和一个基本变量num 。 当在第一个对象上调用super.clone()方法时,除了仅有num的预期副本外,它似乎还创建了对象的深层副本(名称和ID)。 克隆对象obj后,我更改了它的名称和id字段。 如果正在创建浅拷贝,这些更改应该反映在克隆的对象中。 我对吗?

public class Cloning implements Cloneable {
String name;
int num;
Integer id;
Cloning(String name,int num,Integer id)
{
    this.name = name;
    this.num = num;
    this.id = id;
}
public Object clone()
{
    try
    {
        return super.clone();
    }
    catch(CloneNotSupportedException E)
    {
        System.out.println(E.getMessage());
        return null;
    }
}
public void print()
{
    System.out.println(name);
    System.out.println(num);
    System.out.println(id);
}


public static void main(String[] args) {
    // TODO Auto-generated method stub
    Cloning obj = new Cloning("Annu",203,new Integer(3));
    Cloning obj1 = (Cloning)obj.clone();
    obj.name = "Annu_modified";
    obj.num = 204;
    obj.id = new Integer(4);
    obj.print();
    obj1.print();


 }
}

我在运行代码时得到以下输出:

Annu_modified

204

4

Annu

203

3


让我们看看你的例子中的一节: obj.id = new Integer(4); 。 在这里你不会改变id的内部表示 - 你正在给id引用分配新的实例。 IntegerString都是不可变的,因此很难感受到浅拷贝与深拷贝的区别。 尝试添加例如ArrayList属性,并且为了修改它,您可以添加一个新元素obj.myList.add(13);


name和id字段是对String和Integer类型的对象的引用。 当您制作浅拷贝时,新拷贝将指向名称和ID相同的对象。

然后当你这样做

obj.name =“Annu_modified”;

您将obj.name更改为引用String类型的新对象,而obj1.name继续引用旧对象。 如果你可以改变对象的obj.name,它会改变两者。 然而,对于一个字符串,你不能使它成为一个所谓的不可变对象。


试试这个测试

    Cloning obj = new Cloning("Annu",203, 1000);
    Cloning obj1 = (Cloning)obj.clone();
    System.out.println(obj.id == obj1.id);

它打印true ,它意味着克隆对象的id指向Integer的同一个实例,如果它是深度克隆,它将打印false

链接地址: http://www.djcxy.com/p/40799.html

上一篇: Why is the Object class's clone() method giving a deep copy of object?

下一篇: Is clone() in java shallow copy?