【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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2013-10-25 VS报错:DEBUG Assertion Failed!
2013-10-25 cuda&vs2010的属性配置
2012-10-25 CListBox
2012-10-25 图m着色问题