java clone()如何真正使用浅拷贝?

问题描述 投票:3回答:2

我知道可能已经有人问了,但我的问题有所不同。我搜索过,我知道java方法object.clone()使用浅拷贝,这意味着复制引用而不是实际对象。假设我有一只狗类

 Class Dog{
     public Dog(String name, DogTail tail, DogEar ear){
          this.name = name;
          this.tail = tail;
          this.ear  = ear;   
     } 
} 
DogTail t = new DogTail(); 
DogEar ear = new DogEar(); 
Dog dog1 = new Dog("good", t,ear);

假设我想获得dog1的副本。

狗dognew = dog1.clone();

如果这个clone()方法使用浅拷贝,则意味着复制引用。因此,如果我更改上面创建的t对象或ear方法,它将在dognew对象中更改,反之亦然。这个克隆怎么样好?这个问题的诞生是因为有人说创建一个巨大的对象比克隆更糟糕,因为你在使用clone()方法时保存了性能。

java clone
2个回答
1
投票

clone()方法的默认版本创建对象的浅表副本。

对象的浅表副本将具有原始对象的所有字段的精确副本。如果原始对象具有对其他对象的任何引用作为字段,则仅将这些对象的引用复制到克隆对象中,不会创建这些对象的副本。这意味着通过克隆对象对这些对象所做的任何更改都将反映在原始对象中,反之亦然。

要创建对象的深层副本,可以覆盖clone()方法。

protected Object clone() throws CloneNotSupportedException
{
    DogTail tail = (DogTail) this.tail.clone();

    Dog dog = (Dog) super.clone();

    dog.tail = tail;

    return dog;
}

1
投票

“因此,如果我改变上面创建的t对象或者耳朵方法,它会在dognew对象中改变,反之亦然。”

这取决于你所说的“改变”:

如果你的意思是改变DogTail引用的t实例的状态,例如t.setSomething(someValue);,然后是。它是同一个实例,无论是谁导致更改或更改发生的位置。

但是,如果你的意思是改变克隆引用中的t,例如t = new DogTail();t在原来不会受到影响。克隆中的t和原始文件将在此之后引用不同的实例。

© www.soinside.com 2019 - 2024. All rights reserved.