JAVA几种方式实现深拷贝

这篇具有很好参考价值的文章主要介绍了JAVA几种方式实现深拷贝。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JAVA几种方式实现深拷贝

准备

定义两个类用于测试拷贝,类内容如下,目的是深拷贝一个User类的对象:

@Data
@Accessors(chain = true)
public class User {
    private Integer id;
    private Integer age;
    private String name;

    private Car car;

    private String category;
}
@Data
@Accessors(chain = true)
public class Car {
    private Integer id;
    private String color;
    private String name;
} 

实现

package com.demo;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.*;

@Data
@Accessors(chain = true)
public class User implements Cloneable, Serializable {
    private Integer id;
    private Integer age;
    private String name;

    private Car car;

    private String category;

    @Override
    public User clone() throws CloneNotSupportedException {

        return (User) super.clone();
    }

    /**
     * 方法一:最原始的实现方式,通过构造方法手创建
     * 优点:
     * 1.实现简单直观
     * 2.不需要依赖额外的接口和第三方包
     * 缺点:
     * 1.成员变量发生变动需要修改方法,不满足开闭原则;
     * 2.不具有可复用性;
     */
    public User copyUser1() {
        User copyUser = new User()
                .setId(this.getId())
                .setName(this.getName())
                .setAge(this.getAge())
                .setCategory(this.getCategory());
        if (this.getCar() != null) {
            copyUser.setCar(new Car().setId(this.getCar().getId())
                    .setColor(this.getCar().getColor())
                    .setName(this.getCar().getName()));
        }
        return copyUser;
    }

    /**
     * 方法二:使用Object的clone方法实现
     * 优点:
     * 1.较方式1实现更简单,不需要关注copy细节;
     * 2.不需要依赖第三方包;
     * 3.不修改引用类型成员变量不需要修改代码
     * 缺点:
     * 1.需要实现Cloneable,重写父类clone方法,不满足里式替换;
     * 2.且引用类型成员变量发生变动需要修改方法,不满足开闭原则;
     * 3.不具有可复用性;
     */
    public User copyUser2() throws CloneNotSupportedException {
        User cloneUser = this.clone();
        if(this.getCar() != null) {
            cloneUser.setCar(this.getCar().clone());
        }
        return cloneUser;
    }

    /**
     * 方法三:使用Java自带的流方式实现
     * 优点:
     * 1.不破坏类的封装,无需了解被copy对象的内部
     * 2.不需要依赖第三方包
     * 3.代码可复用
     * 缺点:
     * 1.需要实现Serializable接口,会有额外的开销
     */
    public User copyUser3() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (User) ois.readObject();
    }

    /**
     * 方法四:使用第三方包Jackson实现
     * 优点:
     * 1.不破坏类的封装,无需了解被copy对象的内部
     * 2.不需要实现接口
     * 3.代码可复用
     * 缺点:
     * 1.需要依赖第三方包
     * 2.内部实现复杂
     */
    public User copyUser4() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(objectMapper.writeValueAsString(this),User.class);
    }
} 

验证

package com.demo;

import java.io.IOException;

public class CopyDemo {

    public static void main(String[] args) throws IOException, CloneNotSupportedException, ClassNotFoundException {
        User user = new User().setAge(10).setName("李四").setId(3).setCategory("工人");
        user.setCar(new Car().setName("保时捷").setId(999).setColor("黑色"));


        User copyUser1 = user.copyUser1();
        System.out.println("copyUser1:" + copyUser1);
        System.out.println("copyUser1与user对象是否是同一个:" + (System.identityHashCode(user) == System.identityHashCode(copyUser1)));
        System.out.println("copyUser1中的car与user中的car是否是同一个:"+(System.identityHashCode(user.getCar()) == System.identityHashCode(copyUser1.getCar())));

        System.out.println("====================");

        User copyUser2 = user.copyUser2();
        System.out.println("copyUser2:" + copyUser2);
        System.out.println("copyUser2与user对象是否是同一个:" + (System.identityHashCode(user) == System.identityHashCode(copyUser2)));
        System.out.println("copyUser2中的car与user中的car是否是同一个:"+(System.identityHashCode(user.getCar()) == System.identityHashCode(copyUser2.getCar())));

        System.out.println("====================");

        User copyUser3 = user.copyUser3();
        System.out.println("copyUser3:" + copyUser3);
        System.out.println("copyUser3与user对象是否是同一个:" + (System.identityHashCode(user) == System.identityHashCode(copyUser3)));
        System.out.println("copyUser3中的car与user中的car是否是同一个:"+(System.identityHashCode(user.getCar()) == System.identityHashCode(copyUser3.getCar())));

        System.out.println("====================");

        User copyUser4 = user.copyUser4();
        System.out.println("copyUser4:" + copyUser4);
        System.out.println("copyUser4与user对象是否是同一个:" + (System.identityHashCode(user) == System.identityHashCode(copyUser4)));
        System.out.println("copyUser4中的car与user中的car是否是同一个:"+(System.identityHashCode(user.getCar()) == System.identityHashCode(copyUser4.getCar())));

    }


}

验证结果

copyUser1:User(id=3, age=10, name=李四, car=Car(id=999, color=黑色, name=保时捷), category=工人)
copyUser1与user对象是否是同一个:false
copyUser1中的car与user中的car是否是同一个:false
====================
copyUser2:User(id=3, age=10, name=李四, car=Car(id=999, color=黑色, name=保时捷), category=工人)
copyUser2与user对象是否是同一个:false
copyUser2中的car与user中的car是否是同一个:false
====================
copyUser3:User(id=3, age=10, name=李四, car=Car(id=999, color=黑色, name=保时捷), category=工人)
copyUser3与user对象是否是同一个:false
copyUser3中的car与user中的car是否是同一个:false
====================
copyUser4:User(id=3, age=10, name=李四, car=Car(id=999, color=黑色, name=保时捷), category=工人)
copyUser4与user对象是否是同一个:false
copyUser4中的car与user中的car是否是同一个:false

结论

使用java原生推荐方法三,方法一、方法二缺点过于明显,第三方库的方式可以用方法四,spring boot默认的序列化反序列化就是Jackson,另外比照方法四同类的类库也能实现文章来源地址https://www.toymoban.com/news/detail-704431.html

到了这里,关于JAVA几种方式实现深拷贝的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java 实现开启异步线程的几种方式

    在Java中,有多种方式可以实现异步线程以避免在主线程中执行耗时操作导致界面卡顿的问题。以下是几种常用的方式: 使用 Thread 类:可以使用 Thread 类来创建一个新的线程,并在其 run() 方法中执行耗时操作。例如: 使用 Runnable 接口:可以通过实现 Runnable 接口并在其中实现

    2024年02月14日
    浏览(44)
  • Java如何实现下载文件的几种方式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Boy_Martin/article/details/126058565

    2024年02月13日
    浏览(68)
  • Java实现字符串排序的几种方式

    创建实体类(此处引入了lombok) 一、使用List集合中自带的sort方法(字符串的位数保持一致,不一致的情况可以在左边补0,也可以使用String.format()方法补全) 1、在对象排序中使用 2、在字符串排序中使用 二、使用Stream流(字符串的位数保持一致,不一致的情况可以在左边补

    2024年02月11日
    浏览(52)
  • Java生成二维码的几种实现方式

    本文将基于Spring Boot介绍两种生成二维码的实现方式,一种是基于Google开发工具包,另一种是基于Hutool来实现; 下面我们将基于Spring Boot,并采用两种方式实现二维码的生成,对于每一种方式还提供两种类型的二维码返回形式,即:物理文件 和 图片响应流 一、基于Google开发

    2024年02月17日
    浏览(43)
  • java实现调用http请求的几种常见方式

    ------ Oracle中文开发者社区 ------ 如果你想要学习编程,关注本博客,持续获得技术支持,持续获得技术咨询 java开发·企业官方账号 Oracle中国官方账号 Java中国管理部 全网粉丝30万+ 华为云享专家 阿里专家博主 CSDN内容合伙人 CSDN原力计划作者 51CTO专家博主 CSDN博客V账号 毕业于四川

    2024年02月04日
    浏览(54)
  • Java实现HTTP请求的几种方式-HttpURLConnection(一)

    在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)。 准备两个项目: 项目A: 服务提供者 项目B:服务消费者 在项目A中

    2024年02月16日
    浏览(43)
  • java 通过远程URL实现文件下载几种方式

    java环境下通过远程接口实现文件下载几种方式: 使用NIO下载文件, 需要 jdk 1.7+ 利用 commonio 库下载文件,依赖Apache Common IO 文件通道FileChahhel 通过URL直接下载转换成MultipartFile 文件内容 保存地址 文件名称类型(后缀) 使用NIO下载文件 利用Apache common io 库下载文件 使用文件通

    2024年02月03日
    浏览(48)
  • JAVA微服务分布式事务的几种实现方式

    一致性(Consistency) :在分布式系统中所有的数据备份,在同一时刻都保持一致状态,如无法保证状态一致,直接返回错误; 可用性(Availability):在集群中一部分节点故障,也能保证客户端访问系统并得到正确响应,允许一定时间内数据状态不一致; 分区容错性(Partiti

    2024年02月12日
    浏览(51)
  • Java实现HTTP请求的几种方式-CloseableHttpClient(三)

    CloseableHttpClient是在HttpClient的基础上修改更新而来的,这里还涉及到请求头token的设置(请求验证),利用fastjson转换请求或返回结果字符串为json格式,当然上面两种方式也是可以设置请求头token、json的,这里只在下面说明。 基于第一章的测试接口,建立以下程序 创建客户端

    2023年04月20日
    浏览(45)
  • vue深拷贝的几种实现方式

    1、通过递归方式实现深拷贝 比较全面的深拷贝,缺点是较为繁琐 2、JSON.parse(JSON.stringify(obj)) 满足一般使用场景,但无法实现对象中方法(function)的深拷贝 3、jQuery的extend方法实现深拷贝 4、Object.assign(obj1, obj2) 只有一级属性为深拷贝,二级属性后就是浅拷贝 5、扩展运算符 只有

    2024年02月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包