首页 > 其他分享 >深拷贝VS浅拷贝

深拷贝VS浅拷贝

时间:2022-10-18 18:34:39浏览次数:42  
标签:return String Address public VS address 拷贝 id

深拷贝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;
        }
    }
}

标签:return,String,Address,public,VS,address,拷贝,id
From: https://www.cnblogs.com/haveanicedayfh/p/16803619.html

相关文章

  • 对象深拷贝的五种方法
    对象深拷贝的五种方法JSON暴力转化varobj={name:'123'}varobj2=JSON.parse(JSON.stringify(obj这种简单粗暴的方式有局限性,当值为undefined、function、symbol......
  • vscode编辑器自动保存
    我们都知道vscode编辑器写完代码之后,需要ctrl+s来保存代码,不然代码是不会保存的,如果忘记了保存直接在浏览器看效果却始终没有效果,找半天的bug,这样会非常影响效率。实际上......
  • 生成式模型 vs 判别式模型
    生成式模型和判别式模型的概念是机器学习领域非常重要的基础知识,但能准确区分开二者并不是一件非常容易的事情,笔者经常是看一遍忘一遍,为了巩固下知识点,我将从以下几个方面对......
  • [报错] VSCODE无法识别相对路径
    报错背景:在使用VSCODE进行代码运行时,明明是正确的相对路径,文件却无法被打开;报错为:无法找到对应文件;解决方法:打开VSCODE-->setting-->execute-->勾选Executeinfil......
  • VS控件-BackgroundWorker
      查询了一下MSDN文档,其中微软就BackgroundWorker类的功能有这么一个描述(英文的,根据个人理解翻译):BackgroundWorker类允许您在单独的线程上执行某个可能导致用户界面(UI)......
  • vsftpd服务
    vsftpd服务ftp是互联网中进行文件传输的一种协议,基于C/S模式,FTP默认有两个工作端口(20数据传输,21FTP服务端就收客户端发来的指令和)安装FTP服务[root@haha-main-130~]#y......
  • 解决 VS Code C/C++ 代码补全间歇性失效的问题
    最近一个月我的vscode突然开始发癫,正常情况下,在编辑器中输入一段字符应该会弹出自动补全的框框:但是不知道从何时起,我的vscode弹出的框里会出现只有C++关键字,没有任何库函......
  • 规则引擎深度对比,LiteFlow vs Drools!
    前言Drools是一款老牌的java规则引擎框架,早在十几年前,我刚工作的时候,曾在一家第三方支付企业工作。在核心的支付路由层面我记得就是用Drools来做的。难能可贵的是,Drools......
  • github 上的vscode vim配置
    settins.json{ //Vim "vim.autoSwitchInputMethod.defaultIM":"normal", "vim.cursorStylePerMode.replace":"underline-thin", "vim.easymotion":true, "vim.ea......
  • 自己电脑上的vscode vim配置
    setting.json//vscode的vim配置"vim.easymotion":true,"vim.incsearch":true,"vim.leader":"<space>","vim.useSystemClipboard":true,"vim.useCtr......