开发者社区> 青夜之衫> 正文

【java开发系列】—— 深克隆和浅克隆

简介:
+关注继续查看

  Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中。那么什么是深克隆,什么是浅克隆呢。

  【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。

  【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。

  下面的两个例子可以很好的说明他们的区别:

  首先看一下类图

  Husband类有一个对wife的引用,当进行浅克隆的时,wife变量都会指向同一个Wife;而进行深克隆时,会指向不同的Wife。下面进行一下验证:

  【浅克隆】

复制代码
 1 public Object clone() {
 2         Husband husband = null;
 3         try{
 4             husband = (Husband)super.clone();
 5         }catch(CloneNotSupportedException e){
 6             e.printStackTrace();
 7         }finally{
 8             return husband;
 9         }
10     }
复制代码

  【深克隆】

复制代码
 1 public Object deepClone() throws IOException,ClassNotFoundException {
 2         //将对象写到流里
 3         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 4         ObjectOutputStream oos = new ObjectOutputStream(bos);
 5         oos.writeObject(this);
 6         //从流里读回来
 7         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
 8         ObjectInputStream ois = new ObjectInputStream(bis);
 9         return ois.readObject();
10     }
复制代码

  【全部代码】

复制代码
  1 package com.xingoo.clone;
  2 
  3 import java.io.ByteArrayInputStream;
  4 import java.io.ByteArrayOutputStream;
  5 import java.io.IOException;
  6 import java.io.ObjectInputStream;
  7 import java.io.ObjectOutputStream;
  8 import java.io.Serializable;
  9 import java.util.Date;
 10 
 11 class Wife implements Serializable{
 12     private String name;
 13     private Date birthday;
 14     
 15     public Wife(){
 16         name = "芙蓉姐姐";
 17         birthday = new Date();
 18     }
 19     public Date getBirthday(){
 20         return birthday;
 21     }
 22     
 23     public String getName() {
 24         return name;
 25     }
 26     public void setName(String name) {
 27         this.name = name;
 28     }
 29 }
 30 class Husband implements Cloneable,Serializable{
 31     private Wife wife;
 32     private Date birthday;
 33     
 34     public Husband(){
 35         wife = new Wife();
 36         birthday = new Date();
 37     }
 38     
 39     public Wife getWife(){
 40         return wife;
 41     }
 42     
 43     public Date getBirthday(){
 44         return birthday;
 45     }
 46     /**
 47      * 浅克隆一个对象
 48      */
 49     public Object clone() {
 50         Husband husband = null;
 51         try{
 52             husband = (Husband)super.clone();
 53         }catch(CloneNotSupportedException e){
 54             e.printStackTrace();
 55         }finally{
 56             return husband;
 57         }
 58     }
 59     /**
 60      * 利用串行化深克隆一个对象,把对象以及它的引用读到流里,在写入其他的对象
 61      * @return
 62      * @throws IOException
 63      * @throws ClassNotFoundException
 64      */
 65     public Object deepClone() throws IOException,ClassNotFoundException {
 66         //将对象写到流里
 67         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 68         ObjectOutputStream oos = new ObjectOutputStream(bos);
 69         oos.writeObject(this);
 70         //从流里读回来
 71         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
 72         ObjectInputStream ois = new ObjectInputStream(bis);
 73         return ois.readObject();
 74     }
 75 }
 76 public class Test {
 77     public static void main(String[] args){
 78         try{
 79             Husband husband = new Husband();
 80             System.out.println("husband birthday "+husband.getBirthday().getTime());
 81             System.out.println("wife birthday "+husband.getWife().getBirthday().getTime());
 82             System.out.println();
 83             Husband husband1 = (Husband)husband.clone();
 84             System.out.println("husband1 birthday "+husband1.getBirthday().getTime());
 85             System.out.println("wife birthday "+husband1.getWife().getBirthday().getTime());
 86             System.out.println();
 87             System.out.println("是否是同一个husband "+(husband == husband1));
 88             System.out.println("是否是同一个wife "+ (husband.getWife() == husband1.getWife()));
 89             System.out.println();
 90             Husband husband2 = (Husband)husband.deepClone();
 91             System.out.println("husband2 birthday "+husband2.getBirthday().getTime());
 92             System.out.println("wife birthday "+husband2.getWife().getBirthday().getTime());
 93             System.out.println();
 94             System.out.println("是否是同一个husband "+(husband == husband2));
 95             System.out.println("是否是同一个wife "+ (husband.getWife() == husband2.getWife()));
 96         }catch(Exception e){
 97             e.printStackTrace();
 98         }
 99     }
100 }
复制代码

  【运行结果】

复制代码
husband birthday 1414247244668
wife birthday 1414247244668

husband1 birthday 1414247244668
wife birthday 1414247244668
是否是同一个husband false
是否是同一个wife true

husband2 birthday 1414247244668
wife birthday 1414247244668
是否是同一个husband false
是否是同一个wife false
复制代码

 

本文转自博客园xingoo的博客,原文链接:【java开发系列】—— 深克隆和浅克隆,如需转载请自行联系原博主。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
​Java高精度人员定位系统源码,基于Vue+Spring boot开发,运用UWB定位技术
一套运用UWB技术的高精度人员定位系统源码,专业团队研发,可运用于化工厂人员定位,养老院定位,施工人员定位,隧道人员定位,室内管廊定位,车辆定位,物资定位,仓储定位等。
14 0
Java智慧校园电子班牌系统源码 基于Java+springboot+vue+element-ui+mysql开发
Java智慧校园系统源码 智慧学校源码 小程序+电子班牌,有演示,可正常上线运营+可授权 开发环境:Java+springboot+vue+element-ui+mysql 开发语言:Java+springboot+VUE +小程序 全套源码
80 0
Zp
Java开发常用工具网址
Java开发常用工具网址
17 0
IOT智慧物联网平台源码 后台基于JAVA开发 前端HTML
目前web系统功能已实现: 1、 数据实时采集和远程控制; 2、 报警信息管理和报表导出; 3、 自动控制,触发管理; 4、 历史数据,报表导出功能; 5、 子账户和场景授权管理; 6、 场景信息管理;
65 0
Java web 开发涉及多线程和锁定的应用场景有哪些?(邮件发送和接收示例)
Java web 开发中,有一些场景需要用到多线程和锁定,以提高性能、保证数据一致性或实现特定的功能,多线程和锁定提升网站性能、保障数据安全或实现复杂功能的重要技术手段。
34 0
智慧校园源码,智慧学校源码+微信小程序+人脸电子班牌 JAVA开发
技术开发环境:Java+springboot+vue+element-ui+mysql 用的是最新的技术栈,完全满足开发要求。 它是一款集智慧教学、智慧教务、智慧校务于一体的校园管理平台
84 0
电子病历系统源码 EMR电子病历源码 医院电子病历系统 B/S架构 JAVA开发
后端技术选型:SpringBoot框架、Mybatis-Plus、WebSocket、Stomp、Vintage-Engine 前端技术选型:原生HTML、JS、CSS,Jquery、BootStrap、layui、Swf插件、Clipboard剪切板、Echarts、PagedJS打印插件、Prince打印插件、Wkhtmltopdf打印插件等。
56 0
云HIS源码:JAVA开发采用主流技术栈
云HIS系统技术框架: 总体框架: SaaS应用,全浏览器访问 前后端分离,多服务协同 服务可拆分,功能易扩展 云HIS系统技术细节: 前端:Angular+Nginx 后台:Java+Spring,SpringBoot,SpringMVC,SpringSecurity,MyBatisPlus,等 数据库:MySQL + MyCat 缓存:Redis+J2Cache 消息队列:RabbitMQ 任务调度中心:XxlJob 接口技术:RESTful API + WebSocket + WebService 报表组件:itext + POI + ureport2 数据库
42 0
Java学习之路006——Servlet开发
包括引入servlet的api库、IDEA2022配置servlet有关操作,以及servlet的xml配置与注解使用;以及简单的servlet编程实现。
36 0
走过的坑-Java开发
走过的坑-Java开发
26 0
+关注
青夜之衫
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
Java工程师必读手册
立即下载
Java应用提速(速度与激情)
立即下载
Java单元测试实战
立即下载