Java中的深拷贝(深复制)和浅拷贝(浅复制)

深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java。虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑。

浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。

若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝,下面我们着重谈一下深拷贝。

运行下面的程序,看一看浅拷贝:

class Professor0 implements Cloneable {String name;int age;Professor0(String name, int age) {this.name = name;this.age = age;}public Object clone() throws CloneNotSupportedException {return super.clone();}
}class Student0 implements Cloneable {String name;// 常量对象。int age;Professor0 p;// 学生1和学生2的引用值都是一样的。Student0(String name, int age, Professor0 p) {this.name = name;this.age = age;this.p = p;}public Object clone() {Student0 o = null;try {o = (Student0) super.clone();} catch (CloneNotSupportedException e) {System.out.println(e.toString());}return o;}
}public class ShallowCopy {public static void main(String[] args) {Professor0 p = new Professor0("wangwu", 50);Student0 s1 = new Student0("zhangsan", 18, p);Student0 s2 = (Student0) s1.clone();s2.p.name = "lisi";s2.p.age = 30;s2.name = "z";s2.age = 45;System.out.println("学生s1的姓名:" + s1.name + "\n学生s1教授的姓名:" + s1.p.name + "," + "\n学生s1教授的年纪" + s1.p.age);// 学生1的教授}
}

s2变了,但s1也变了,证明s1的p和s2的p指向的是同一个对象。这在我们有的实际需求中,却不是这样,因而我们需要深拷贝:

class Professor implements Cloneable {String name;int age;Professor(String name, int age) {this.name = name;this.age = age;}public Object clone() {Object o = null;try {o = super.clone();} catch (CloneNotSupportedException e) {System.out.println(e.toString());}return o;}
}class Student implements Cloneable {String name;int age;Professor p;Student(String name, int age, Professor p) {this.name = name;this.age = age;this.p = p;}public Object clone() {Student o = null;try {o = (Student) super.clone();} catch (CloneNotSupportedException e) {System.out.println(e.toString());}o.p = (Professor) p.clone();return o;}
}public class DeepCopy {public static void main(String args[]) {long t1 = System.currentTimeMillis();Professor p = new Professor("wangwu", 50);Student s1 = new Student("zhangsan", 18, p);Student s2 = (Student) s1.clone();s2.p.name = "lisi";s2.p.age = 30;System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);// 学生1的教授不改变。long t2 = System.currentTimeMillis();System.out.println(t2-t1);}
}

当然我们还有一种深拷贝方法,就是将对象串行化:

import java.io.*;
//Serialization is time-consuming
class Professor2 implements Serializable {/*** */private static final long serialVersionUID = 1L;String name;int age;Professor2(String name, int age) {this.name = name;this.age = age;}
}class Student2 implements Serializable {/*** */private static final long serialVersionUID = 1L;String name;// 常量对象。int age;Professor2 p;// 学生1和学生2的引用值都是一样的。Student2(String name, int age, Professor2 p) {this.name = name;this.age = age;this.p = p;}public Object deepClone() throws IOException, OptionalDataException,ClassNotFoundException {// 将对象写到流里ByteArrayOutputStream bo = new ByteArrayOutputStream();ObjectOutputStream oo = new ObjectOutputStream(bo);oo.writeObject(this);// 从流里读出来ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());ObjectInputStream oi = new ObjectInputStream(bi);return (oi.readObject());}}public class DeepCopy2 {/*** @param args*/public static void main(String[] args) throws OptionalDataException,IOException, ClassNotFoundException {long t1 = System.currentTimeMillis();Professor2 p = new Professor2("wangwu", 50);Student2 s1 = new Student2("zhangsan", 18, p);Student2 s2 = (Student2) s1.deepClone();s2.p.name = "lisi";s2.p.age = 30;System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 学生1的教授不改变。long t2 = System.currentTimeMillis();System.out.println(t2-t1);}}

但是串行化却很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。

本文转自:http://www.cnblogs.com/shuaiwhu/archive/2010/12/14/2065088.html

Java中Cloneable接口的浅复制与深复制相关推荐

  1. JAVA中浅复制与深复制

    來源:http://coolmist.javaeye.com/blog/127455 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引 ...

  2. java引用复制_Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy; // ...

  3. java自我复制_原型模式--自我复制(结合Java浅复制与深复制)

    原型模式,字面上的理解,以原型为标杆的模式. 原型模式其实就是从一个对象再创建另外一个可定制对象,而且不需知道任何创建的细节. 我们可以用原型示例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. ...

  4. java clone(浅复制和深复制)的前世今生

    之前只是听说clone,很高级的样子,一直没有用过,感觉日常开发好像用不到似的,谁知道这段时间的开发,发现clone非常好用,就专门学习了一下. 前世 先说说clone的由来吧,只知道它的用法,而不知 ...

  5. Java中实现接口与继承的区别

    ** Java中实现接口与继承的区别 ** 首先,先来了解一下什么是接口和继承.接口一般是使用interface来定义的.接口定义同类的定义类似,分为接口的声明和接口体,其中接口体由常量定义和方法定义 ...

  6. Objective-C 入门(七)协议 protocol(JAVA中的接口)

    Objective-C 入门(七)协议 protocol(JAVA中的接口) 接口的作用想必大家都比较了解 OV中的 protocol 相比接口作用相似 语法稍有不同 1.先来看声明一个协议 在创建文 ...

  7. Java中的接口命名[关闭]

    本文翻译自:Interface naming in Java [closed] Most OO languages prefix their interface names with a capita ...

  8. java中接口什么时候用_我什么时候应该在java中使用接口?

    在Java中精确使用接口的一个很好的例子将是理想的,适用于任何特定的规则. 看看丹以前所有的问题,他似乎只是逐字逐句地张贴家庭作业/考试问题. 令人惊讶的是,这些不是考试题或其他-今天才找到这个网站, ...

  9. Java 中 Comparable 接口的意义和用法.

    在之前的博文中已经介绍了Java中Collection 接口和 Collections类. http://blog.csdn.net/nvd11/article/details/21516075 一, ...

最新文章

  1. 【Java】 LeetCode 622. 设计循环队列 (有关实现循环队列的讲解)
  2. 测试Robotium
  3. ubuntu16.04安装英伟达(NVIDIA)驱动——run文件安装
  4. python编程入门指南 明日科技-python从入门到项目实践明日科技三剑客书籍视频...
  5. step3 . day5 数据结构之线性表 栈和队的应用-球钟问题
  6. C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序
  7. 互联网晚报 | 04月07日 星期四 |​ ​​​​刘强东卸任京东集团CEO,徐雷接任;世卫组织:中医药对治疗新冠有效...
  8. java 调用dll内存泄露_对 精致码农大佬 说的 Task.Run 会存在 内存泄漏 的思考
  9. 23种设计模式(十八)状态变化之备忘录
  10. Eclipse下载及汉化(官方最新)
  11. 弱密码、未授权加固/修复建议
  12. 2021年深度学习哪些方向比较新颖,处于上升期或者朝阳阶段,比较有研究潜力?...
  13. 操作系统概念之定义和功能
  14. 文学写作素材网站分享
  15. vue实现导入表格数据【纯前端实现】
  16. 基于RWEQ模型的土壤风蚀模数估算及其变化归因分析
  17. 科学美国人》如何评价转基因?支持与反对之外的第三条道路
  18. 没有 XXX 的手册页条目
  19. 计算机 博士 论文要求,计算机学院博士生发表论文要求.doc
  20. Ubuntu/Linux Server 服务器系统安装

热门文章

  1. AUC的含义以及Python代码手动实现
  2. MFC串口调试工具教程
  3. SQLTXPLAIN
  4. [游戏策划] 读书笔记
  5. 视频教程-HTML5+CSS3项目实战详解-HTML5/CSS
  6. handoff (wimax of nist)
  7. matlab一些常用的技巧函数
  8. Certificate verification failed: The certificate is NOT trusted.解决方案
  9. android马达测试,MotorTest(马达测试)手机版-MotorTest(马达测试)安卓版下载v1.31-领航下载站...
  10. Xv6操作系统导论(第二章)