深拷贝和浅拷贝

断鸿 2019年07月13日 130次浏览

[toc]

引用拷贝和对象拷贝

    @AllArgsConstructor
    @Data
    class User implements Cloneable {
        private String name;
        private int age;

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
		/**
     * 引用拷贝和对象拷贝
     */
    @Test
    public void referenceCopyAndObjectCopy() throws CloneNotSupportedException {

        User user = new User("tom", 10);
        //引用拷贝
        User user1 = user;
        //输出的hashCode一致,说明是一个对象
        //cn.zerohy.bug.sample.DeepCopyAndShallowCopyTest$1User@184f6be2
        //cn.zerohy.bug.sample.DeepCopyAndShallowCopyTest$1User@184f6be2
        System.out.println(user);
        System.out.println(user1);

        //对象拷贝
        User user2 = (User) user.clone();
        //新对象
        //cn.zerohy.bug.sample.DeepCopyAndShallowCopyTest$1User@184f6be2
        //cn.zerohy.bug.sample.DeepCopyAndShallowCopyTest$1User@56aac163
        System.out.println(user);
        System.out.println(user2);

    }

浅拷贝

    @Data
    @ToString(callSuper = true)
    @AllArgsConstructor
    class Room implements Cloneable {
        private User user;
        private int id;
        private String roomName;

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

    /**
     * 浅拷贝
     */
    @Test
    public void shallowCopy() throws CloneNotSupportedException {
        User user = new User("Jone", 12);
        Room room = new Room(user, 1001, "蓬莱阁");
        Room clone = (Room) room.clone();

        //(User(name=Jone, age=12), id=1001, roomName=蓬莱阁)
        System.out.println(room);
        System.out.println(clone);

        clone.setId(200);
        clone.setRoomName("岳阳楼");
        clone.getUser().setAge(50);
        clone.getUser().setName("Mike");

        //改变clone对象中的user属性,原对象中的user属性也改变了,说明克隆时user属性是引用拷贝
        //(User(name=Mike, age=50), id=1001, roomName=蓬莱阁)
        //(User(name=Mike, age=50), id=200, roomName=岳阳楼)
        System.out.println(room);
        System.out.println(clone);
    }

深拷贝

    /**
     * 深拷贝
     */
    @Test
    public void deepCopy() {

        /**
         * 深拷贝有多种方式:
         *  1、重写clone方法,有缺陷,对于引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦
         *  2、通过序列化和反序列化的方式,如先将room实例序列化成json,再将json数据反序列化成room对象
         */

    }