Day16 objectAPI2-深度克隆

完成对FirstLevel对象的深度克隆。

public class day1601 {
    public static void main(String[] args) throws CloneNotSupportedException {
        //测试Object拷贝
        FirstLevel.ThirdLevel thirdLevel = new FirstLevel.ThirdLevel(10, 20);
        FirstLevel.SecondLevel secondLevel = new FirstLevel.SecondLevel(1, 2.2, thirdLevel);
        FirstLevel  firstLevel = new FirstLevel(30,0.5,secondLevel);
        System.out.println("原对象:"+firstLevel);
        //利用clone方法进行复制
        FirstLevel firstClone= (FirstLevel) firstLevel.clone();
        System.out.println("克隆对象:"+firstLevel);
        //修改原始对象
        secondLevel.secondIntValue=10000;
        thirdLevel.thirdIntValue=100;
        System.out.println("修改后的原对象:"+firstLevel);
        System.out.println("修改后的克隆对象:"+firstClone);
    }
}

class FirstLevel implements Cloneable {
    int firstIntValue;
    double firstDoubleValue;
    SecondLevel second;

    public FirstLevel(int firstIntValue, double firstDoubleValue,
                      SecondLevel second) {
        this.firstIntValue = firstIntValue;
        this.firstDoubleValue = firstDoubleValue;
        this.second = second;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //利用Object的Clone方法,return super.clone();复制FirstLevel对象本身
        FirstLevel clone = (FirstLevel) super.clone();
        //再利用SecondLevel实现的深度克隆clone()方法,完成对second所指对象的深度克隆
        //并修改复制后的SecondLevel克隆对象中,second引用的值,让它指向复制的ThirdLevel对象
        clone.second = (SecondLevel) second.clone();
        return clone;
    }

    @Override
    public String toString() {
        return "FirstLevel{" + "firstIntValue=" + firstIntValue +
                ",firstDoubleValue=" + firstDoubleValue + ",second=" +
                second + "}";
    }

    static class SecondLevel implements Cloneable {
        int secondIntValue;
        double secondDoubleValue;
        ThirdLevel third;

        public SecondLevel(int secondIntValue, double secondDoubleValue,
                           ThirdLevel thirdObj) {
            this.secondIntValue = secondIntValue;
            this.secondDoubleValue = secondDoubleValue;
            this.third = thirdObj;
        }

        //SecondLevel完成对自己的深度克隆
        @Override
        protected Object clone() throws CloneNotSupportedException {
            //利用Object的Clone方法,克隆自己本身
            SecondLevel clone = (SecondLevel) super.clone();
            //再利用ThirdLevel实现的深度克隆clone()方法,完成对thirdObj所指向对象的深度克隆
            //并修改复制之后的SecondLevel克隆对象中,thirdObj引用的值,让它指向复制的ThirdLevel对象
            ThirdLevel thirdLevel = (ThirdLevel) third.clone;
            clone.third = thirdLevel;
            return clone;
        }

        @Override
        public String toString() {
            return "SecondLevel{" + "secondIntValue" + secondIntValue +
                    ",secondDoubleValue=" + secondDoubleValue +
                    ",third=" + third + "}";
        }
    }

    static class ThirdLevel implements Cloneable {
        public Object clone;
        int thirdIntValue;
        double thirdDouleValue;

        public ThirdLevel(int thirdIntValue, double thirdDouleValue) {
            this.thirdIntValue = thirdIntValue;
            this.thirdDouleValue = thirdDouleValue;
        }

        @Override
        public String toString() {
            return "ThirdLevel{" + "thirdIntValue=" + thirdIntValue +
                    ",thirdDoubleValue=" + thirdDouleValue + "}";
        }
        /*完成对ThirdLevel对象的深度拷贝,只不过ThirdLevel知道自己只包含基本数据类型的值
         * 所以,直接利用Object的clone方法,就可以完成对自己的深度克隆*/

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
}

思路:实现深度克隆的思路(类似于递归):
1.首先每个类,知道自己有哪些成员变量,成员变量中哪些是引用类型成员变量
2.然后让每个类自己实现对自己的深度克隆方法
3.实现深度克隆就变得简单了:
a.首先利用super.clone()即Object的clone方法,完成对自己的克隆
b.如果本类中有引用类型的成员,那么因为所有类都实现了对自己的深度克隆
所以直接调用引用类型的成员所指向对象的clone方法,让他们自己完成自己的深度克隆
c.将引用类型成员变量的值,让他们指向深度克隆后的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值