前言

想来大家应该会被标题招引进来,但我顶真表明,对于初学Java的朋友们来说,尤其是学到clone的朋友来说物超所值。

  • 标题的意思理解起来便是本体被复制体所影响,要是各位还太能明白这句话的话,那么我将以代码的形式给各位聪明的大脑一点小小的指点。

代码–浅复制

package InterFace;//Comparable
//主要知识点
//clone
class Money implements Cloneable{
    public double money = 3.5;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public Money m;
    public Person(String name) {
        this.name = name;
        m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("xiaowang");
        //将person1目标克隆为person2
        Person person2 = (Person) person1.clone();
        System.out.println("修正之前:"  person1.m.money);//3.5
        System.out.println("修正之前:"  person2.m.money);//3.5
        person2.m.money = 7;
        System.out.println("修正之后:"  person1.m.money);//?
        System.out.println("修正之后:"  person2.m.money);//?
    }
}

图上代码为简略的clone中我标出了两个”?”,大家无妨思考一下输出的值为多少?

  • System.out.println("修正之后:" person1.m.money);7

  • System.out.println("修正之后:" person2.m.money);7

大家可能会以为person1.m.money的值为3.5,而person2.m.money的值为7。 究竟咱们改动的是值是person2,也便是代码 person2.m.money = 7;。但从成果而言,person1却因为person2的值改动而改动了。这样的状况便是浅克隆。

图析

为什么你克隆了我,我却要随你而改动?

文字剖析

1.假定person1所处的地址为0X55,也能够看出name的地址为0X55(首地址—-类似于数组),设定m的地址为0X66

然后执行克隆句子,克隆之后,此刻person2的地址为0X11,复制后的name地址则为0X11;而m的地址仍为0X66不变。person1person2都指向着money,所以之后修正money的值之后输出的值都为7.

出现这样的成果并非clone有局限性,而是程序员没有更好的运用clone办法。所以咱们这里提出—深复制:彻底复制出一个独立于本来目标的目标。

代码–深复制(由浅复制完善而来)

class Person implements Cloneable{
    public String name;
    public Money m;
    public Person(String name) {
        this.name = name;
        m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //return super.clone();
        Person tmp = (Person) super.clone();//创立局部变量接纳 过程1
        tmp.m = (Money) this.m.clone();//克隆m   过程2
        return tmp;//将值送回person2
    }
}

浅转深复制的逻辑思路

想要处理无法复制彻底的问题,就要回归起点,根据浅复制的终究成果展现,回归最初的问题—也便是

Person person2 = (Person) person1.clone();

这一句子错误的执行,没有将money进行复制。–那么咱们就要重写clone办法。

  • 创立局部变量tmp来接纳name。
  • 将m克隆出来
  • 回来给person2

为什么你克隆了我,我却要随你而改动?
此刻代码的输出成果就为:

  • System.out.println("修正之后:" person1.m.money);3.5

  • System.out.println("修正之后:" person2.m.money);7

clone想要怎么使用彻底取决于程序员自己。