浅谈浅克隆(shallow clone)和 深克隆(deep clone)
区别就在于是否对对象中的引用变量所指向的对象进行拷贝。
1.浅克隆/浅复制/浅拷贝
浅拷贝是指在拷贝对象时,对于基本数据类型的变量会重新复制一份,而对于引用类型的变量只是对引用进行拷贝,没有对引用指向的对象进行拷贝。
2.深克隆/深复制/深拷贝
深拷贝是指在拷贝对象时,同时会对引用指向的对象进行拷贝。
示例代码:
1 import java.util.Date; 2 3 class Wife implements Cloneable { 4 private String name; 5 private Date birthday; 6 7 public Wife(){ 8 } 9 10 public Wife(String name, Date birthday) { 11 this.name = name; 12 this.birthday = birthday; 13 } 14 15 public Date getBirthday(){ 16 return birthday; 17 } 18 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 26 public Object clone() throws CloneNotSupportedException { 27 return super.clone(); 28 } 29 30 public String toString() { 31 return "Wife [name=" + name + ", birthday=" + birthday + "]"; 32 } 33 34 } 35 36 class Husband implements Cloneable { 37 private String name; 38 private Wife wife; 39 40 public Husband(){ 41 } 42 43 public Husband(String name, Wife wife) { 44 this.name = name; 45 this.wife = wife; 46 } 47 48 public Wife getWife() { 49 return wife; 50 } 51 52 public void setWife(Wife wife) { 53 this.wife = wife; 54 } 55 56 public String getName() { 57 return name; 58 } 59 60 public void setName(String name) { 61 this.name = name; 62 } 63 64 /** 65 * 浅克隆一个对象 66 * @throws CloneNotSupportedException 67 */ 68 public Object shallowClone() throws CloneNotSupportedException { 69 return super.clone(); 70 } 71 /** 72 * 利用串行化深克隆一个对象,把对象以及它的引用读到流里,在写入其他的对象 73 * @return 74 * @throws Exception 75 */ 76 public Object deepClone() throws Exception { 77 Husband husband = (Husband) super.clone(); 78 husband.wife = (Wife) this.wife.clone(); 79 return husband; 80 } 81 } 82 83 public class Test { 84 public static void main(String[] args) throws Exception{ 85 //浅克隆 86 Wife w1 = new Wife("曹夫人", new Date()); 87 Husband h1 = new Husband("曹先生", w1); 88 Husband h2 = (Husband) h1.shallowClone(); 89 90 System.out.println("原型对象:" + h1.getName() + "--" + h1.getWife()); 91 System.out.println("克隆对象:" + h2.getName() + "--" + h2.getWife()); 92 93 w1.setName("张夫人"); 94 95 System.out.println("\n--------------------------修改克隆对象的属性值后---------------------------\n"); 96 97 System.out.println("原型对象:" + h1.getName() + "--" + h1.getWife()); 98 System.out.println("克隆对象:" + h2.getName() + "--" + h2.getWife()); 99 100 System.out.println("\n---------------------------------------------------------------------\n"); 101 102 //深克隆 103 Wife w2 = new Wife("曹夫人", new Date()); 104 Husband h3 = new Husband("曹先生", w2); 105 Husband h4 = (Husband) h3.deepClone(); 106 107 System.out.println("原型对象:" + h3.getName() + "--" + h3.getWife()); 108 System.out.println("克隆对象:" + h4.getName() + "--" + h4.getWife()); 109 110 w2.setName("张夫人"); 111 112 System.out.println("\n--------------------------修改克隆对象的属性值后---------------------------\n"); 113 114 System.out.println("原型对象:" + h3.getName() + "--" + h3.getWife()); 115 System.out.println("克隆对象:" + h4.getName() + "--" + h4.getWife()); 116 117 118 } 119 }
控制台输出:
原型对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018] 克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018] --------------------------修改克隆对象的属性值后--------------------------- 原型对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018] 克隆对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018] --------------------------------------------------------------------- 原型对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018] 克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018] --------------------------修改克隆对象的属性值后--------------------------- 原型对象:曹先生--Wife [name=张夫人, birthday=Mon Jan 15 18:00:35 CST 2018] 克隆对象:曹先生--Wife [name=曹夫人, birthday=Mon Jan 15 18:00:35 CST 2018]