深拷贝VS浅拷贝

深拷贝VS浅拷贝

  • 深拷贝将对象及值复制过来,两个对象修改其中任意的值,另一个值不会改变。

  • 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意值,另一个值都会随之改变。

深拷贝和浅拷贝会增加内存吗?

深拷贝:增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。

浅拷贝:增加了一个指针指向已存在的内存地址。

为什么要使用克隆?

对象的拷贝需要使用克隆,如果想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要使用克隆了,Java语言中克隆针对的是类的实例。

如何实现对象克隆?

实现Cloneable接口并重写Object类中的clone()方法。

/*1、所有对象都实现克隆方法;*/
public class CloneExample1 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address(1,"广州");
        People people = new People(1,"Java", address);
        //  克隆
        People people1 = people.clone();

        //  修改原型
        people1.setId(2);
        people1.address.setCity("深圳");
        //  输出比对结果
        System.out.println("原型对象:" + people);
        System.out.println("克隆对象:" + people1);
    }


    //  用户类
    static class People implements Cloneable{
        private Integer id;
        private String name;
        private Address address;

        public People(Integer id, String name, Address address) {
            this.id = id;
            this.name = name;
            this.address = address;
        }

        @Override
        protected People clone() throws CloneNotSupportedException {
            People people = (People)super.clone();
            people.setAddress(this.address.clone());
            return people;
        }

        @Override
        public String toString() {
            return "People{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", address=" + address +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public People setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getName() {
            return name;
        }

        public People setName(String name) {
            this.name = name;
            return this;
        }

        public Address getAddress() {
            return address;
        }

        public People setAddress(Address address) {
            this.address = address;
            return this;
        }
    }


    //  地址类
    static class Address implements Cloneable{
        private Integer id;
        private String city;
        public Address(Integer id, String city) {
            this.id = id;
            this.city = city;
        }

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

        @Override
        public String toString() {
            return "Address{" +
                    "id=" + id +
                    ", city='" + city + '\'' +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public Address setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getCity() {
            return city;
        }

        public Address setCity(String city) {
            this.city = city;
            return this;
        }
    }
}

实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

package clone.deep.example1;

import java.io.*;
/*3、使用 JDK 自带的字节流实现深克隆;
* 通过字节流将原型对象的值写进内存,然后再从内存中读取数据进行克隆。
* 因为是从内存中读取值所以不存在共享内存地址。
注意:原型对象以及引用对象都要实现Serializable 接口,
* 标识自己可以被序列化,否则会抛出异常
*  (java.io.NotSerializableException)。
 */
public class CloneExample2 {

    public static void main(String[] args) {
        Address address = new Address(1,"广州");
        People people1 = new People(1,"Java", address);
        //  通过字节流实现克隆
        People people2 = StreamClone.clone(people1);
        //  修改原型
        people1.setId(2);
        people1.getAddress().setCity("深圳");
        //  输出比对结果
        System.out.println("原型对象:" + people1);
        System.out.println("克隆对象:" + people2);
    }


    static class StreamClone{
        /**
         * 通过字节流实现克隆
         */
        public static <T extends Serializable> T clone(T obj) {
            T cloneObj = null;
            try {
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bo);
                oos.writeObject(obj);
                oos.close();
                //  分配内存,写入原型对象,生成新对象
                ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
                ObjectInputStream oi = new ObjectInputStream(bi);
                //  返回生成的新对象
                cloneObj = (T) oi.readObject();
                oi.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return cloneObj;
        }
    }
    //  用户类
    static class People implements Serializable{
        private Integer id;
        private String name;
        private Address address;
        public People(Integer id, String name, Address address) {
            this.id = id;
            this.name = name;
            this.address = address;
        }

        @Override
        public String toString() {
            return "People{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", address=" + address +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public People setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getName() {
            return name;
        }

        public People setName(String name) {
            this.name = name;
            return this;
        }

        public Address getAddress() {
            return address;
        }

        public People setAddress(Address address) {
            this.address = address;
            return this;
        }
    }


    //  地址类
    static class Address implements Serializable {
        private Integer id;
        private String city;
        public Address(Integer id, String city) {
            this.id = id;
            this.city = city;
        }

        @Override
        public String toString() {
            return "Address{" +
                    "id=" + id +
                    ", city='" + city + '\'' +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public Address setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getCity() {
            return city;
        }

        public Address setCity(String city) {
            this.city = city;
            return this;
        }
    }
}

使用第三方工具实现深克隆:

JDK 自带的字节流实现深克隆org.apache.commons.lang.SerializationUtils.clone(Serializable object)

/**
 * 深克隆实现方式四:通过 apache.commons.lang 实现
 */
public class CloneExample3 {

    public static void main(String[] args) {
        Address address = new Address(1,"广州");
        People people1 = new People(1,"Java", address);
        //  通过字节流实现克隆
        People people2 = (People) SerializationUtils.clone(people1);
        //  修改原型
        people1.setId(2);
        people1.getAddress().setCity("深圳");
        //  输出比对结果
        System.out.println("原型对象:" + people1);
        System.out.println("克隆对象:" + people2);
    }



    //  用户类
    static class People implements Serializable{
        private Integer id;
        private String name;
        private Address address;
        public People(Integer id, String name, Address address) {
            this.id = id;
            this.name = name;
            this.address = address;
        }

        @Override
        public String toString() {
            return "People{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", address=" + address +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public People setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getName() {
            return name;
        }

        public People setName(String name) {
            this.name = name;
            return this;
        }

        public Address getAddress() {
            return address;
        }

        public People setAddress(Address address) {
            this.address = address;
            return this;
        }
    }


    //  地址类
    static class Address implements Serializable {
        private Integer id;
        private String city;
        public Address(Integer id, String city) {
            this.id = id;
            this.city = city;
        }

        @Override
        public String toString() {
            return "Address{" +
                    "id=" + id +
                    ", city='" + city + '\'' +
                    '}';
        }

        public Integer getId() {
            return id;
        }

        public Address setId(Integer id) {
            this.id = id;
            return this;
        }

        public String getCity() {
            return city;
        }

        public Address setCity(String city) {
            this.city = city;
            return this;
        }
    }
}

posted @   haveanicedayfh  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示