先说定义,

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。

深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

深拷贝与浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是深拷贝(值拷贝)),是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这时,你修改两个中的任意一个都不会影响另一个;而对于对象或引用数据在进行浅拷贝时,只是将对象的引用复制了一份,也就是内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任意一个变量的值都是改变内存地址所存储的值,因此两个变量的值都会改变。

简单来说,两者实际上都是为目标对象赋值,浅拷贝复制的是基本数据类型的数据以及引用类型的地址值,对于引用类型实际上是共用一个地址值(个人理解),深拷贝对于基本数据类型一样,对于引用类型是重新new了一个新对象并复制,用的是新的地址



举例:在项目中,我们常用beanUtils.copyProperties(),(不管是spring自带的还是apache的,都一样)来给具有较多相同字段的对象赋值,避免通过set的方式,开发效率较低过于繁琐,但是在bean对象结构较复杂,层级较多时会有一些问题,如下:

我先定义一个User实体

@Data
public class User {private String username;private String password;private Address address;@Datapublic static class Address {private Integer menpaihao;private String jiedao;private List<Integer> numList;}
}

然后进行测试

    @Testpublic void Test(){User user = new User();user.setUsername("张三");user.setPassword("123");User.Address address = new User.Address();address.setMenpaihao(110);address.setJiedao("成华大道");List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);address.setNumList(list);user.setAddress(address);User user1 = new User();BeanUtils.copyProperties(user,user1);System.out.println("user1 = " + user1);System.out.println("user = " + user);User user2 = initUser(user1);System.out.println("user = " + user);System.out.println("user2 = " + user2);System.out.println(VM.current().addressOf(user));System.out.println(VM.current().addressOf(user2));System.out.println("user的Address地址值 = " + VM.current().addressOf(user.getAddress()));     System.out.println("user2的Address的地址值 = " + VM.current().addressOf(user2.getAddress()));}public User initUser(User user){List<Integer> numList = user.getAddress().getNumList();for (int i = 0; i < numList.size(); i++) {numList.set(i,0);}return user;}

测试结果

可以发现将User复制到User1之后,我再对User1进行修改,改变它属下的numList里面的值,(而源对象User我一直是没有动过的),这时候再对两个进行打印,发现源对象User里面的属性值也被修改了,所以还是有点问题的。此时虽然最外层属性值没问题,地址也不一样,但是最内层的Address属性地址值是共用的,所以一变都变。

目前我的解决方式有两种,一种是老老实实通过set的方式一一赋值,效率还高,另一种就是通过深拷贝了。

深拷贝举例其中一种较简单的方式:

1. 导入依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

2. 对bean对象以及其引用的其他实体类对象都要实现序列化

3.使用SerializationUtils.clone()克隆,返回的对象就是克隆后的对象

浅拷贝之copyProperties()相关推荐

  1. spring BeanUtils.copyProperties浅拷贝之特殊的Boolean

    背景 在开发过程中, 在数据库查询和接口调用过程中,为了隔离,我们往往会将查询出来的对象(包括数据库返回和接口返回)和对外提供的实体对象隔离开来.此时就需要把一个对象的属性拷贝到目标对象中 通常有2种 ...

  2. BeanUtils.copyProperties()使用详解+在不同包的区别

    一. 两个包下的BeanUtils.copyProperties对比 BeanUtils是开发中常用到的工具类. 而获取这一工具类常用的方法有两种 org.springframework.beans. ...

  3. 对象克隆-深拷贝,浅拷贝,直接赋值

    1背景分析 在 Java 开发中,对象拷贝或者说对象克隆是常有的事,对象克隆最终都离不开直接赋值.浅拷贝.深拷贝 这三种方式,我们常用的对象的转化方式,使用的是spring的 BeanUtils.co ...

  4. Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝

    1. 类继承 如下代码 class A(object):def show(self):print 'This is calss A'class B(A):def show(self):print 'T ...

  5. 对象特性---->深拷贝与浅拷贝

    浅拷贝:简单的赋值拷贝操作. 深拷贝:在堆区申请一块空间,进行拷贝操作. 浅拷贝:编译器提供的拷贝构造函数对传入值进行赋值拷贝操作 #include<iostream> using nam ...

  6. ES6深拷贝与浅拷贝

    小感在前 React学习与开发过程要经历一个相当长的准备阶段,此前看阮一峰老师的文章中,他就特别提到这一点.但是,由于React框架或者说是一种优秀的前端架构实在太诱人,所以,掌握这项技术所涉及的技术 ...

  7. Objective C浅拷贝和深拷贝

    ##浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.如: char* str = (char*)malloc(100); char* str2 = str; 复制代码 浅 ...

  8. C++深拷贝与浅拷贝

    浅拷贝就是成员数据之间的一一赋值:把值赋给一一赋给要拷贝的值.但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件..当 值拷贝的时候,两个对象就有用共同的资源,同时对资源可以 ...

  9. Java中的浅拷贝与深拷贝

    一.引用拷贝与对象拷贝 class Person implements Cloneable{private String name;private int age;...省略get和set方法 pro ...

最新文章

  1. C++中的vector的用法
  2. 整理:warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
  3. 多线程:什么是ThreadLocal?应用场景?
  4. 符号引用(typeglob,别名)与全局变量的修改
  5. Python 2.7:字符串乱码问题的解决
  6. 前端javascript知识(二)
  7. javascript 15位和18位身份证的正则表达式及其验证
  8. php中phpmyadmin打不开,解决phpMyAdmin打不开的方法
  9. 怎么禁止浏览器自动保存密码?
  10. 读后有感 - UI设计师必知:线框图、原型和视觉稿
  11. java判断读到末尾_Java Web入门之java--第一节 java 简介及开发环境安装
  12. 转Windows 2003服务器安全配置终极技巧
  13. DriverManager 连接不同的连接池
  14. Golang学习笔记3——常量与运算符
  15. 剑指offer——面试题44:扑克牌顺子
  16. 不能说的秘密-重载、重写与继承中的构造方法
  17. Word快速构建座位表
  18. 5.3 10篇美食类小红书爆文拆解【玩赚小红书】
  19. 电子电路中,PVDD、CVDD、VPP、 VDD、 AVDD、VCC分别是指什么电源?各起什么作用?
  20. 华为od面试java经历

热门文章

  1. 为什么数据库表名需要表前缀
  2. CNC加工中心操机全过程,学数控必备
  3. Elasticsearch 实现对Word、PDF等文件进行全文检索
  4. u盘linux 修复grub,ubuntu修复grub,u盘引导问题
  5. 常见的html转义字符
  6. u盘属于计算机软件吗,u盘属于哪一类商标
  7. 码率控制、VBR、CBR
  8. BZOJ_P1123 [POI2008]BLO(无向图割点)
  9. C/C++编程笔记:C++中的isspace()及其在计算空格字符中的应用
  10. 图像的基本操作--反转、放大等