大家好,我是烤鸭:

今天分享一下浅copy和深copy。

1.   深copy

什么是深copy,只复制原对象属性值,不管地址。

说一下业务场景:

如果我想创建一个对象,只是对原对象的某个属性值改变。普通的做法就是new 一个对象,然后setXXX,如果属性特别多的话不方便,这时候就是需要深copy。复制出来的对象属于不同的地址,改变复制对象的属性值不会影响原对象。

TestClone.java:

package com.xxx.xxx.utils;import org.junit.Test;import java.io.Serializable;/*** Created by  on 2018/7/23*/
public class TestClone {public TestClone() {}@Testpublic void testDeepCopy(){Person person1 = new Person();person1.id = "id1";person1.name = "name1";person1.sex = "sex1";System.out.println("复制前person:"+person1);Person clone = CloneUtils.clone(person1);System.out.println("这是深copy后的对象:"+clone);System.out.println("=========改变深copy后的对象属性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";System.out.println("copy的对象:"+clone);System.out.println("复制后person:"+person1);}}
class Person implements Serializable,Cloneable{String id;String name;String sex;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", name='" + name + '\'' +", sex='" + sex + '\'' +'}';}@Overridepublic Person clone() {Person person = null;try {person = (Person) super.clone();} catch (CloneNotSupportedException ignored) {System.out.println(ignored.getMessage());}return person;}
}

CloneUtils.java:

package com.xxx.xxx.utils;import java.io.*;public class CloneUtils {@SuppressWarnings("unchecked")public static <T extends Serializable> T clone(T obj){T cloneObj = null;try {//写入字节流ByteArrayOutputStream out = new ByteArrayOutputStream();ObjectOutputStream obs = new ObjectOutputStream(out);obs.writeObject(obj);obs.close();//分配内存,写入原始对象,生成新对象ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());ObjectInputStream ois = new ObjectInputStream(ios);//返回生成的新对象cloneObj = (T) ois.readObject();ois.close();} catch (Exception e) {e.printStackTrace();}return cloneObj;}
}

结果如图:

2.   浅copy

与深copy相对应,浅copy就是复制的对象指向了原对象的地址值。如果复制的对象属性值改变,原对象也会随之改变。

如果是单个对象的话,用引用copy吧。

如果是对象中还有属性是对象的话。

Person.java 和 Man.java

class Person  implements Cloneable, Serializable  {String id;String name;String sex;Man man;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Man getMan() {return man;}public void setMan(Man man) {this.man = man;}@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", name='" + name + '\'' +", sex='" + sex + '\'' +", man=" + man +'}';}@Overridepublic Person clone() {Person person = null;try {person = (Person) super.clone();} catch (CloneNotSupportedException ignored) {System.out.println(ignored.getMessage());}return person;}
}
class Man{String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Man{" +"name='" + name + '\'' +", age='" + age + '\'' +'}';}
}
 /*** 浅复制* @throws IOException* @throws ClassNotFoundException*/@Testpublic void testShallowCopy() throws IOException, ClassNotFoundException {Person person1 = new Person();Man man = new Man();man.name = "man1";man.age = "age1";person1.id = "id1";person1.name = "name1";person1.sex = "sex1";person1.man = man;System.out.println("复制前person:"+person1);Person clone = person1.clone();System.out.println("这是浅copy后的对象:"+clone);System.out.println("=========改变浅copy后的对象属性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";clone.man.name = "man2";clone.man.age = "age2";System.out.println("copy的对象:"+clone);System.out.println("复制后person:"+person1);}

如图:

可以看出,改变了man的属性,原对象中的man属性值也改变了。这就是浅copy。

如果不想这样的话,就把man也clone。

man实现clone接口,重写clone方法:

class Man implements Cloneable{String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Man{" +"name='" + name + '\'' +", age='" + age + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

修改copy方法:

        Man man2 = (Man) person1.man.clone();man2.name = "man2";man2.age = "age2";clone.man = man2;

如图:

3.    引用copy

  /*** 引用复制* @throws IOException* @throws ClassNotFoundException*/@Testpublic void testQuoteCopy() throws IOException, ClassNotFoundException {Person person1 = new Person();person1.id = "id1";person1.name = "name1";person1.sex = "sex1";System.out.println("复制前person:"+person1);Person clone = person1;System.out.println("这是引用copy后的对象:"+clone);System.out.println("=========改变引用copy后的对象属性=====================");clone.id = "id2";clone.name = "name2";clone.sex = "sex2";System.out.println("copy的对象:"+clone);System.out.println("复制后person:"+person1);}

如图:

Java 深copy 浅copy 引用copy相关推荐

  1. retain copy(浅复制) mutablecopy (深复制)

    http://blog.csdn.net/xdrt81y/article/details/24331103 口诀: 1浅3深 NSArray copy (浅) 返回NSArray NSArray  m ...

  2. python教程:深copy浅copy

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 1. 赋值 赋值其实只是传递对象引用,引用对象 ...

  3. Python中的浅复制(shallow copy)和深复制(deep copy)

    文章目录 python值管理方式 深复制与浅复制的使用及区别 近期杂事太多,博客一直没更新,9月最后一天了,总得写点吧 今天记一下以前碰到过,最近又碰到的问题:python的深复制和浅复制 神奇的py ...

  4. python学习 - copy模块的浅复制(copy)与深复制(deepcopy)

    python学习 - copy模块的浅复制(copy)与深复制(deepcopy) 简介 copy.copy()详解 copy.deepcopy()详解 简介 在使用列表或者字典进行传递参数的时候,可 ...

  5. java zero copy 实现,关于Zero Copy

    概述 很多web应用都会有大量的静态文件.我们通常是从硬盘读取这些静态文件,并将完全相同的文件数据写到response socket.这样的操作需要较少的CPU,但是效率有些低,它需要经过如下的过程: ...

  6. python中的几种copy用法_Python3中copy模块常用功能及其他几种copy方式比较

    1.简单的共享引用: python中内置有小整数常量池和字符串常量池,在某个范围内的相同的数字或字符串分别赋给不同的变量,这些不同的变量都是指向同一块内存地址,这就是所谓的共享引用,举几个简单的例子: ...

  7. SAP WMSD集成之Copy WM Quantity – Not Copy WM qty as delivery qty into delivery But PGI

    SAP WM&SD集成之Copy WM Quantity – Not Copy WM qty as delivery qty into delivery But PGI 本文继续DEMO SA ...

  8. no copy constructor available or copy constructor is declared #39;explicit#39;

    今天新写了一个类.然后对这个类使用STL中的vector,碰到错误: no copy constructor available or copy constructor is declared 'ex ...

  9. copy语法 postgre_PostgreSql中COPY的用法

    一.Copy的基本语法 Copy的作用是复制数据在数据表和文件之间. Copy在Postgresql中的语法是(来自文档): 1. 将文件中的数据复制到表中: COPY table_name [ ( ...

最新文章

  1. python数字图像的行 宽的不同处 cv2.resize(1389,1500) p1列宽 p2 行高 stop2.shape 得(640,960,3) v1列宽 v2 行高 v3 通道数
  2. 搭建dubbo项目解决dubbo.xml标签报错的问题
  3. 迅速掌握Unix编程
  4. Cocos Creator导出场景和预制的问题
  5. Linux下基于C/C++的Socket编程基础
  6. 从一片空白到世界领先,中国通信翻身逆袭史
  7. linux之chroot命令
  8. framework7的改进,以及与vue组合使用遇到的问题以及解决方法 (附vue的原理)
  9. 史上最全的OpenCV入门教程
  10. Android11(R) system_ext 分区 system_ext_specific 属性
  11. Android-failed to set system property
  12. 英语发音规则---/ŋ/与/ŋg/的读音区别
  13. unity shader中关于Tags的整理
  14. 前方高能预警!三星Galaxy A6s带你闹元旦
  15. 杰理之GSENSOR【篇】
  16. 第7周编程题在线测试
  17. MVC |分部视图 PartialView()
  18. 保护计算机数据库,保护Access2000数据库的安全
  19. 送给要健身或者准备健身的男朋友女朋友基友们 想让你们和我一样踏上条不归路
  20. redmine配置邮箱提醒步骤(qq企业邮箱和个人邮箱)

热门文章

  1. 前端学习(3025):vue+element今日头条管理-侧边导航菜单
  2. [html] 你是如何理解html与css分离的?
  3. [jQuery] jQuery是通过哪个方法和Sizzle选择器结合的?
  4. 工作224:当前函数造成
  5. 前端学习(2413):关于有默认子路由的路由name
  6. 前端学习(2043)vue之电商管理系统电商系统之优化web.config.js的配置文件
  7. 前端学习(1930)vue之电商管理系统电商系统之美化一层循环的UI结构删除业务逻辑实现
  8. java学习(65):类访问static修饰的内部类
  9. Linux 用C/C++创建新文件并写入内容
  10. 用 vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)