Java对象深拷贝的几种方式

2023-11-12

对象拷贝

项目开发过程中很多时候需要进行对象复制,可是有的时候会发生复制后的对象,在原对象改变后也相应发生改变,这种时候就有问题了。所以很有必要了解对象的深拷贝,以及深拷贝的几种方式。

new 对象

手动 new 新的对象,一个属性一个属性的赋值,这种方式比较原始,也比较繁琐,容易出错,直接略过。

重载 clone()方法

对象中的基本类型是不需要考虑深拷贝的,深拷贝只针对对象类型或者对象集合对象。对于这种,可以分别重载对象中的clone方式

示例: OrderVO有三个字段

// (基本类型)
private String orderNo;
// (对象类型)
private UserVo userVo;
// (对象集合类型)
private List<GoodsVO> goodsVoList;   

OrderVo

package test.copy.vo;

import java.util.ArrayList;
import java.util.List;

public class OrderVO implements Cloneable{
    private String orderNo;

    private UserVO userVO;

    private List<GoodsVO> goodsVOList;

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public UserVO getUserVO() {
        return userVO;
    }

    public void setUserVO(UserVO userVO) {
        this.userVO = userVO;
    }

    public List<GoodsVO> getGoodsVOList() {
        return goodsVOList;
    }

    public void setGoodsVOList(List<GoodsVO> goodsVOList) {
        this.goodsVOList = goodsVOList;
    }

    @Override
    public OrderVO clone() {
        try {
            OrderVO orderVO = (OrderVO) super.clone();
            orderVO.setUserVO(this.userVO.clone());
            if (goodsVOList != null && goodsVOList.size() > 0) {
                List<GoodsVO> goodsList = new ArrayList<>();
                for (GoodsVO goodsVO : goodsVOList) {
                    goodsList.add(goodsVO.clone());
                }
                orderVO.setGoodsVOList(goodsList);
            }
            return orderVO;
        } catch (CloneNotSupportedException e) {
            System.out.println("exception happened");
        }
        return null;
    }
}

UserVo

package test.copy.vo;

public class UserVO implements Cloneable{
    private String userName;

    private int age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public UserVO clone() {
        try {
            UserVO userVO = (UserVO) super.clone();
            return userVO;
        } catch (CloneNotSupportedException e) {
            System.out.println("exception happened");
        }
        return null;
    }
}

GoodsVo

package test.copy.vo;

import java.math.BigDecimal;

public class GoodsVO implements Cloneable{

    private String goodsName;

    private BigDecimal price;

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }


    @Override
    public GoodsVO clone() {
        try {
            GoodsVO userVO = (GoodsVO) super.clone();
            return userVO;
        } catch (CloneNotSupportedException e) {
            System.out.println("exception happened");
        }
        return null;
    }
}

测试类

package test.copy.vo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class TestCopy {

    public static void main(String[] args) {
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderNo("T0001001010");
        UserVO userVO = new UserVO();
        userVO.setUserName("Ellen Max");
        userVO.setAge(45);
        orderVO.setUserVO(userVO);
        List<GoodsVO> goodsVOList = new ArrayList<>();
        GoodsVO goodsVO1 = new GoodsVO();
        goodsVO1.setGoodsName("迪士尼门票");
        goodsVO1.setPrice(new BigDecimal("556"));

        GoodsVO goodsVO2 = new GoodsVO();
        goodsVO2.setGoodsName("东方明珠门票");
        goodsVO2.setPrice(new BigDecimal("125"));
        goodsVOList.add(goodsVO1);
        goodsVOList.add(goodsVO2);
        orderVO.setGoodsVOList(goodsVOList);

        OrderVO orderVO1 = orderVO.clone();
        System.out.println("clone success");

        orderVO.setOrderNo("A000123123");
        orderVO.getUserVO().setUserName("Steve Jobs");
        orderVO.getGoodsVOList().get(0).setGoodsName("香港迪士尼门票");
        System.out.println("改变原始orderVo");
        System.out.println("orderVO1.userVo.userName 没有改变");
        System.out.println("orderVO1.goodsVOList.get(0).goodsName 没有改变");
    }
}

JSON序列号

这种方式比较简单,就是对象转json字符串,再利用JSONObject转成对象,parseObject或者parseArray方法

Apache Commons Lang里面的SerializationUtils

这种方式有两点需要注意

  • 类都实现Serializable接口
  • 转换需要是同一种类,不通类之间无法转换,否则会报错

OrderDTO

package test.copy.vo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class OrderDTO implements Serializable {

    private String orderNo;

    private UserDTO userDTO;

    private List<GoodsDTO> goodsDTOList;

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public UserDTO getUserDTO() {
        return userDTO;
    }

    public void setUserDTO(UserDTO userDTO) {
        this.userDTO = userDTO;
    }

    public List<GoodsDTO> getGoodsDTOList() {
        return goodsDTOList;
    }

    public void setGoodsDTOList(List<GoodsDTO> goodsDTOList) {
        this.goodsDTOList = goodsDTOList;
    }
}

UserDTO

package test.copy.vo;

import java.io.Serializable;

public class UserDTO implements Serializable {
    private String userName;

    private int age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

GoodsDTO

package test.copy.vo;

import java.io.Serializable;
import java.math.BigDecimal;

public class GoodsDTO implements Serializable {

    private String goodsName;

    private BigDecimal price;

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

}

Test


package test.copy.vo;

import org.apache.commons.lang3.SerializationUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class CommonsLangCopyTest {
    public static void main(String[] args) {
        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setOrderNo("T0001001010");
        UserDTO userDTO = new UserDTO();
        userDTO.setUserName("Ellen Max");
        userDTO.setAge(45);
        orderDTO.setUserDTO(userDTO);
        List<GoodsDTO> goodsDTOList = new ArrayList<>();
        GoodsDTO goodsDTO1 = new GoodsDTO();
        goodsDTO1.setGoodsName("迪士尼门票");
        goodsDTO1.setPrice(new BigDecimal("556"));

        GoodsDTO goodsDTO2 = new GoodsDTO();
        goodsDTO2.setGoodsName("东方明珠门票");
        goodsDTO2.setPrice(new BigDecimal("125"));
        goodsDTOList.add(goodsDTO1);
        goodsDTOList.add(goodsDTO2);
        orderDTO.setGoodsDTOList(goodsDTOList);

        // 不需要指定class类型,因为只能为同一个类
        OrderDTO orderDTO1 = SerializationUtils.clone(orderDTO);
        System.out.println("clone success");


        orderDTO.setOrderNo("A000123123");
        orderDTO.getUserDTO().setUserName("Steve Jobs");
        orderDTO.getGoodsDTOList().get(0).setGoodsName("香港迪士尼门票");

        System.out.println("change source attribute");
    }
}

使用TypeReference

这个可以将任意json字符串转成成任意形式,如

  • 对象
  • List对象
  • Map<String, List>
	// 字符串转List<Object>
    List<ActuaryAssessmentReqDTO.Drug> drugList = JSONObject.parseObject(JSONObject.toJSONString(obj), new TypeReference<List<ActuaryAssessmentReqDTO.Drug>>() {});
    // 字符串转HashMap<String, List<List<ErrorInfo>>>
    Map<String, List<List<ErrorInfo>>> resultInfo = JSONObject.parseObject(obj, new TypeReference<HashMap<String, List<List<ErrorInfo>>>>() {});

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java对象深拷贝的几种方式 的相关文章

  • nginx配置文件之“location ~ .*\. (js

    nginx里面的location配置语法 location url 选项参数匹配 表示精准匹配 表示uri以某个常规字符串开头 理解为匹配 url路径即可 nginx不对url做编码 因此请求为 static 20 aa 可以被规则 sta
  • Proteus仿真STM32的课设实例4——stm32简易测频率

    本教程是基于STM32的嵌入式仿真大作业 源文件链接 https pan baidu com s 1fU4isp7UXTtUFHwpt76zzw pwd 9x7t 提取码 9x7t 使用 Proteus 仿真32单片机 实现了可以测量正弦波
  • 不想dto套dto可以这样写

    之前都是要新建个dto文件的 偶然看到别人这样写 简单记录一下 Data public class GdtDailyBalanceContent List
  • 编程教育是孩子计算机启蒙的好伙伴

    网络上关于 少儿编程 的利好资讯铺天盖地 印证着这一行业的欣欣向荣 国际上 很多发达国家早已把编程教育纳入小学课程表 重视儿童学习编程成为教育的主流 格物斯坦小坦克认为 由此看来从小就培养孩子学习编程 真的有必要 其实 大多数家长对编程可能
  • 没有公网IP,怎么实现外网访问内网视频监控

    以海康威视监控为例 先在内网部署好监控系统 通过本地浏览器输入监控设备管理地址 登录管理后台 在管理后台可成功查看摄像头视频画面即内网监控系统搭建成功 找到配置界面查看设备端口信息 记下HTTP访问端口80 默认网址访问端口 及服务数据传输
  • devops

    1 环境准备 使用的虚拟机环境centos7 8 Jenkins 10 21 90 111 k8sMaster 10 21 90 113 k8sNode 10 21 90 114 同步主机时区为亚洲 并同步时间 root linux nod
  • React Hooks的history带参数跳转,并获取参数

    跳转页面带参数 history push pathname admin test query id user id name user name 跳转后获取参数 const query props console log query nam
  • esp8266学习笔记(5)——连接wifi、AP、UDP通信

    终于开始接触网络了 基础不行 这个摸索了有点久 还好网上资料多 有些细节还是没有怎么吃透 哈哈 开始联网了 ESP8266有三种模式 station模式 0x01 soft AP模式 0x02 soft AP station模式 0x03

随机推荐

  • spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property

    spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property
  • 项目管理培训记录

    PMP 十大知识领域 五大过程组 IPD 易经
  • 【Spring】Spring源码(一)循环依赖与bean生命周期

    Spring循环依赖 文章目录 Spring循环依赖 Spring解决循环依赖 Spring生命周期 1 扫描 扫描是否有bean注入 2 解析 解析是不是单例模式 是否懒加载 3 调用扩展 查看是否赋予额外的扩展功能 4 验证 根据第二步
  • 数学笔记/scipy 笔记:豪斯多夫距离(Hausdorff )

    1 概念 一个点集中的点到另一个点集的最短距离的最大值 1 1 容易受噪声的影响 1 2 性质 当A和B都是闭集的时候 Hausdorff距离满足 2 举例 3 python 实现 3 1 掉包 scipy 3 1 1 数据 from sc
  • 管窥广电总局的TVOS,又一个Android定制版?

    原文地址 http news cecb2b com info 20140711 2515776 shtml 2014年149号通知 国家新闻出版广电总局关于大力开展智能电视操作系统TVOS1 0规模应用试验 加快推动广播电视终端标准化智能化
  • 解决flex布局弹性布局使用justify-content:space-between后最后一行多个元素排版问题

    解决flex布局弹性布局使用justify content space between后最后一行多个元素排版问题 1 当一行有三个元素的时候直接加个伪类 原图 想要实现的效果 html代码 div class floor centerLis
  • SQL 查询优化之 WHERE 和 LIMIT 使用索引的奥秘

    奇怪的慢sql 我们先来看2条sql 第一条 select from acct trans log WHERE acct id 1000000000009000757 order by create time desc limit 0 10
  • 为什么Java源文件中的public类 必须与文件名相同

    每个编译单元 文件 只能有一个public类 这么做的意思是 每个编译单元只能有一个公开的接口 而这个接口就由其public类来表示 而非public修饰的类都是为了给public修饰的类所做支撑的 从软件架构设计和安全性设计上得出的结论
  • 最新Mysql8.0.27安装配置基本使用

    目录 下载MySQL 配置目录文件 初始化Mysql 安装Mysql 配置环境 基本使用 下载MySQL 官方下载地址 https dev mysql com downloads 下载后解压 路径自定义 并新建文件夹data 配置目录文件
  • Vulkan教程翻译之十 创建 Descriptor Set

    原文链接 https vulkan lunarg com doc sdk 1 2 131 2 windows tutorial html 09 init descriptor set html 创建 Descriptor Set 这一章节的
  • haproxy搭建web集群

    目录 HAProxy HAProxy的主要特性 HAProxy负载均衡调度策略 HAProxy的配置文件解读 HAProxy部署 1 安装环境 2 下载haproxy安装包 并安装 3 新建haproxy用户 并在 etc 下创建hapro
  • linux 目录创建与删除 centos7

    root wyflinux tmp cd tmp 进入 tmp 目录 选择在tmp联系目录创建 root wyflinux tmp mkdir p test1 test2 test3 test4 mkdir p 直接创建多级目录 递回 ro
  • 【数据库系统概论】第四、五章:数据库安全性、完整性

    视频 参考资料 内容来自参考链接和视频 文章目录 第四章 数据库安全性 安全性概述 安全性控制 试图机制 审计 数据加密 第五章 数据库完整性 正确性 相容性 三大完整性 第四章 数据库安全性 安全性概述 不安全因素 非授权用户对数据库的恶
  • 用Unity3D实现太阳系仿真

    用Unity3D模拟太阳系仿真 模拟要求 写一个程序 实现一个完整的太阳系 其他星球围绕太阳的转速必须不一样 且不在一个法平面上 操作步骤 1 创建如下结构 sun 里包括8大行星 并且设置好距离和大小 建立结构 建议用2D显示来直观设置距
  • 收藏

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 本文转自 视觉算法 图片来源于网络 语义分割在自然数据集的分割效果不断进步 有研究逐步应用到了遥感领域 尤其是高分辨率遥感影像 由于遥感图像具有海量数据 尺度依赖 空间相
  • 《Kubernetes部署篇:Ubuntu20.04基于containerd部署kubernetes1.24.17集群(多主多从)》

    一 架构图 如下图所示 二 环境信息 1 部署规划 主机名 K8S版本 系统版本 内核版本 IP地址 备注 k8s master 63 1 24 17 Ubuntu 20 04 5 LTS 5 15 0 69 generic 192 168
  • 两个数的简单计算器

    两个数的简单计算器 本题要求编写一个简单计算器程序 可根据输入的运算符 对2个整数进行加 减 乘 除或求余运算 题目保证输入和输出均不超过整型范围 方法一 include
  • 13.网络爬虫—多进程详讲(实战演示)

    网络爬虫 多进程详讲 一 进程的概念 二 创建多进程 三 进程池 四 线程池 五 多进程和多线程的区别 六 实战演示 北京新发地线程池实战 前言 个人简介 以山河作礼 Python领域新星创作者 CSDN实力新星认证 第一篇文章 1 认识网
  • iso文件添加服务器,服务器挂载本地iso文件

    RHEL6 3配置文件共享 2 autofs服务 在上篇博文中我们介绍了利用NFS服务设置文件共享 在客户端必须要先将服务器端的NFS共享目录挂载到本地 然后才能使用 其实在Linux系统中还为我们提供了另外一种更为简单的使用NFS共享的方
  • Java对象深拷贝的几种方式

    对象拷贝 项目开发过程中很多时候需要进行对象复制 可是有的时候会发生复制后的对象 在原对象改变后也相应发生改变 这种时候就有问题了 所以很有必要了解对象的深拷贝 以及深拷贝的几种方式 new 对象 手动 new 新的对象 一个属性一个属性的