首页 > 其他分享 >关于浅拷贝,深拷贝以及深拷贝的实现方法

关于浅拷贝,深拷贝以及深拷贝的实现方法

时间:2024-07-08 22:01:31浏览次数:13  
标签:city String Address Person 关于 address 拷贝 方法 public

浅拷⻉:

浅拷⻉会在堆上创建⼀个新的对象(区别于引⽤拷⻉的⼀点),不过,如果原对象内部的属性是引⽤类型的话,浅拷⻉会直接复制内部对象的引⽤地址,也就是说拷⻉对象和原对象共⽤同⼀个内部对象。

深拷⻉ :

深拷⻉会完全复制整个对象,包括这个对象所包含的内部对象。

我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力。

在这里插入图片描述


如何实现深拷贝(深克隆)?

示例代码

class Person implements Cloneable {
    String name;
    int age;
    Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person clonedPerson = (Person) super.clone();
        clonedPerson.address = (Address) this.address.clone();
        return clonedPerson;
    }
}

class Address implements Cloneable {
    String city;
    String state;

    public Address(String city, String state) {
        this.city = city;
        this.state = state;
    }

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

public class DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("San Francisco", "CA");
        Person person1 = new Person("John", 30, address);

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

        System.out.println("Person1 address: " + person1.address.city); // 输出: San Francisco
        System.out.println("Person2 address: " + person2.address.city); // 输出: San Francisco

        person2.address.city = "Los Angeles";

        System.out.println("Person1 address after modification: " + person1.address.city); // 输出: San Francisco
        System.out.println("Person2 address after modification: " + person2.address.city); // 输出: Los Angeles
    }
}

注意以上是实现了cloneable接口。当然这种方法实在是太过于麻烦了。使用序列化来深克隆一个对象要简单得多,尤其是成员变量中有很多引用类型的时候。

使用序列化和反序列化来深拷贝一个对象
import java.io.*;

// 地址类实现Serializable接口
class Address implements Serializable {
    String city;
    String state;

    public Address(String city, String state) {
        this.city = city;
        this.state = state;
    }

    @Override
    public String toString() {
        return city + ", " + state;
    }
}

// 人类实现Serializable接口
class Person implements Serializable {
    String name;
    int age;
    Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return name + " (" + age + "), " + address;
    }

    // 使用序列化进行深拷贝
    public Person deepCopy() throws IOException, ClassNotFoundException {
        // 将对象写入字节流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        oos.flush();
        oos.close();

        // 从字节流读取对象
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Person) ois.readObject();
    }
}

public class DeepCopyUsingSerialization {
    public static void main(String[] args) {
        try {
            Address address = new Address("San Francisco", "CA");
            Person person1 = new Person("John", 30, address);

            // 深拷贝person1
            Person person2 = person1.deepCopy();

            System.out.println("Person1: " + person1); // 输出: John (30), San Francisco, CA
            System.out.println("Person2: " + person2); // 输出: John (30), San Francisco, CA

            // 修改person2的地址
            person2.address.city = "Los Angeles";

            System.out.println("Person1 after modification: " + person1); // 输出: John (30), San Francisco, CA
            System.out.println("Person2 after modification: " + person2); // 输出: John (30), Los Angeles, CA
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

如果觉得有帮助,欢迎点赞、收藏,以及小小支持一下。
本人博客地址:朗朗繁星的博客

标签:city,String,Address,Person,关于,address,拷贝,方法,public
From: https://blog.csdn.net/weixin_43997353/article/details/140279640

相关文章

  • 关于Python中的series详解与应用
    引言近期在学习Python的过程中学到了Pandas库,它是数据处理操作中一款非常强大且流行的工具。而Pandas的两个核心数据结构是Series和DataFrame(下一篇文章便会进行有关学习)。本篇将详细介绍Series,主要包括它的定义、创建方法、常用操作、应用场景以及与其他数据结构的比较,仅为......
  • 期刊论文一般包含引言、方法与材料、实验、结果、讨论、结论六个部分,或者将结果与讨论
    问题描述:期刊论文一般包含引言、方法与材料、实验、结果、讨论、结论六个部分,或者将结果与讨论合并就是五个部分。引言、方法与材料、实验、结果、讨论、结论六个部分在撰写时,分别包含哪些内容,这六个部分的区别是什么?问题解答:在撰写期刊论文时,通常包括引言(Introduction)、方......
  • ollama IsEmbedding() 方法含义与 BERT
     func(m*Model)IsEmbedding()bool{returnslices.Contains(m.Config.ModelFamilies,"bert")||slices.Contains(m.Config.ModelFamilies,"nomic-bert")}该函数用于判断模型是否是BERT嵌入模型。它通过检查模型配置中的ModelFamilies字段是否包含"bert"或"n......
  • 加入了trim()方法,没有去掉多余空格
    原因:    直接使用String自带的trim方法,返回给原String类型变量(如修改前代码)。原始的customerMessage字符串对象的值是不会发生变化的,因为String类型都是不可变的,只能通过创建新的字符串对象来表达修改后的值。 修改前代码importcn.hutool.core.util.StrUtil;......
  • Java方法重写,匿名对象,抽象类
    1-方法重写什么是方法重写?子类和父类出现了一模一样的方法的声明(方法名,参数列表)为什么要学习方法重写?当子类需要使用父类的功能,但是父类的功能又满足不了子类,那么子类需要重写,这样既可以使用父类的功能,也可以增加新的功能如果进行方法重写?子......
  • git合并代码方法
    你合并代码用merge还是用rebase?macrozheng 2024年07月08日14:10 江苏 1人听过 以下文章来源于古时的风筝 ,作者风筝古时的风筝.写代码是一种爱好,写文章是一种情怀。mall学习教程官网:macrozheng.com你们平时合并代码的时候用merge还是rebase?我问了......
  • 隐藏属性ID和保留特大文件夹名称都是关于文件系统中文件和文件夹管理的不同方面。
    隐藏属性ID和保留特大文件夹名称都是关于文件系统中文件和文件夹管理的不同方面。让我们分别讨论它们:1.隐藏属性ID隐藏属性ID通常是指文件系统中用于标识和管理文件或文件夹隐藏状态的标识符。在许多操作系统中,文件和文件夹可以设置不同的属性来控制其是否在文件浏览器中可见。这......
  • vue.xx 使用方法汇总
    Vue.prototype.xx作用:挂载全局方法使用场景一:将自定义函数或方法进行全局挂载,方便全局使用。exportfunctiongetData(param1){}import{getData}from"@/xx/xx";Vue.prototype.getData=getData;this.getData(param1)使用场景二:安装自定义插件import{Message......
  • 4个方法帮助你解决RAR解压文件时提示密码错误问题
    在日常工作和学习中,我们经常需要处理各种压缩文件,这些文件有时为了保护内容安全,会被设置密码。然而,在解压这些文件时,如果遇到“密码错误”的提示,可能会让人感到十分棘手。今天,我们就来探讨四种方法,帮助你轻松解决这一问题。方法一:确认密码的正确性首先,也是最基础的一步,就是......
  • SQL注入方法
    目录前言如何测试与利用注入点手工注入思路工具sqlmap-r-u-m--level--risk-v-p--threads-batch-smart--os-shell--mobiletamper插件获取数据的相关参数前言记录一些注入思路和经常使用的工具,后续有用到新的工具和总结新的方法再继续补充。如何测试与利用注入点手工下面的现......