千家信息网

Java中浅拷贝和深拷贝该怎么理解

发表于:2025-02-16 作者:千家信息网编辑
千家信息网最后更新 2025年02月16日,这篇文章给大家介绍Java中浅拷贝和深拷贝该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java浅拷贝深拷贝浅拷贝和深拷贝涉及到了Object类中的clone()方法实
千家信息网最后更新 2025年02月16日Java中浅拷贝和深拷贝该怎么理解

这篇文章给大家介绍Java中浅拷贝和深拷贝该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Java浅拷贝深拷贝

浅拷贝和深拷贝涉及到了Object类中的clone()方法

实现浅拷贝

浅拷贝的实现需要类重写clone()方法

浅拷贝会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝

如果属性是基本类型,拷贝的就是基本类型的值;

如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象,导致两个对象的引用不等

实现浅拷贝很简单只需要将类实现Cloneable接口然后重写clone方法即可

class Person implements Cloneable {    String name;    int age;    public Person() {    }    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    /**         * 重写clone()方法         *         * @return         * @throws CloneNotSupportedException         */    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();    }    @Override    public String toString() {        return "Person{" +            "name='" + name + '\'' +            ", age=" + age +            '}';    }}

测试浅拷贝特性

public void testClone() throws CloneNotSupportedException {    Person person1 = new Person();    person1.setName("ccy");    person1.setAge(20);    Person person2 = (Person) person1.clone();    //查看浅拷贝效果    System.out.println(person1);    System.out.println(person2);    System.out.println(person1.getName() == person2.getName());    //验证clone()的特性    System.out.println(person1.clone() != person1);    System.out.println(person1.clone().getClass() == person1.getClass());    //如果是基本类型浅拷贝直接赋值值,如果是引用类型浅拷贝指向其内存地址即共享内存地址    //改变person1的引用类型String属性的值,引用发生改变    person1.setName("zfs");    System.out.println(person2.getName());}

实现深拷贝

对于上述的问题虽然拷贝的两个对象不同,但其内部的一些引用还是相同的,怎么样绝对的拷贝这个对象,使这个对象完全独立于原对象呢?就使用我们的深拷贝了。深拷贝:在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量。

在具体实现深拷贝上,这里提供两个方式,重写clone()方法和序列法。

重写clone()方法

如果使用重写clone()方法实现深拷贝,那么要将类中所有自定义引用变量的类也去实现Cloneable接口实现clone()方法。对于字符类可以创建一个新的字符串实现拷贝。但是对于自定义类需要实现cloneable重写clone,这样做就太麻烦了所以我们使用序列化

序列化

序列化后将二进制字节流内容写到一个媒介(文本或字节数组),然后是从这个媒介读取数据,原对象写入这个媒介后拷贝给clone对象,原对象的修改不会影响clone对象,因为clone对象是从这个媒介读取。

熟悉对象缓存的知道我们经常将Java对象缓存到Redis中,然后还可能从Redis中读取生成Java对象,这就用到序列化和反序列化。一般可以将Java对象存储为字节流或者json串然后反序列化成Java对象。因为序列化会储存对象的属性但是不会也无法存储对象在内存中地址相关信息。所以在反序列化成Java对象时候会重新创建所有的引用对象。

在具体实现上,自定义的类需要实现Serializable接口

class Person implements Serializable {    String name;    int age;    public Person() {    }    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "Person{" +            "name='" + name + '\'' +            ", age=" + age +            '}';    }    protected Person deepClone() throws Exception {        //序列化        ByteArrayOutputStream bos = new ByteArrayOutputStream();        ObjectOutputStream oos = new ObjectOutputStream(bos);        oos.writeObject(this);        //反序列化        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());        ObjectInputStream ois = new ObjectInputStream(bis);        return (Person) ois.readObject();    }}

测试方法

public void testClone() throws Exception {    Person person1 = new Person();    person1.setName("ccy");    person1.setAge(20);    Person person2 = person1.deepClone();    System.out.println(person1.getName() == person2.getName());}

可以看到两个引用对象的地址并不同,成功实现了深拷贝

关于Java中浅拷贝和深拷贝该怎么理解就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

拷贝 对象 序列 方法 地址 类型 内存 属性 两个 媒介 内容 接口 不同 变量 字符 就是 数据 时候 更多 特性 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 cod16一直链接服务器 郑州大学软件开发三本 河北手机软件开发多少钱 苹果六怎么删除应用数据库 海思平台软件开发外包 网络安全资质申报 水利部网络安全大数据分析平台 redmine软件开发管理 广电网络安全用电措施 数据库加密函数支持数字签名 网络安全标准化试题 知网数据库文件格式 如何把两个数据库合并 智能互联网络技术专业怎么样 双硕软件开发有限公司怎么样 数据库启动需要时间吗 数据库可以有多个主要数据吗 疫情期间网络安全知识 HCNC网络技术实验指南 公交车实时数据库 听中国无网络技术有限公司 20年后软件开发会消失吗 服务器什么时候维修比较短 内蒙古鑫洆互联网研发科技 计算机网络技术层面上的技术 属于数据库安全性遭到破坏 科技风片头 科技感 互联网 共青城市网络技术有限公司 数据库应用技术形考1答案 国家网络安全周宣传部署会议
0