浅克隆与深克隆的区别:
l 浅克隆:被复制的所有变量都具有与原来对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
l 深克隆:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
注意:如果一个类需要可以被克隆,需要实现clone方法和实现Clone接口,二者缺一不可。
首先实现浅克隆:
DeepClone.java
package com.model.Prototype; import java.util.ArrayList; import java.util.List; public class DeepClone implements Cloneable { /** * 一个集合 */ List<SomeThing> list = new ArrayList<SomeThing>(); public List<SomeThing> getList() { return list; } public void setList(List<SomeThing> list) { this.list = list; } /* * 实现的克隆方法 */ public Object clone(){ try{ /* * 常用的克隆调用方法 */ return super.clone(); }catch(CloneNotSupportedException e){ return null; } } }
SomeThing.java:
package com.model.Prototype; public class SomeThing implements Cloneable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public SomeThing(String name){ super(); this.name = name; } }
TestClone2.java:
package com.model.Prototype; /* * 测试深克隆 */ public class TestClone2 { public static void main(String[] args) { //源对象 DeepClone dc = new DeepClone(); dc.getList().add(new SomeThing("一个对象")); //克隆对象 DeepClone dcc = (DeepClone)dc.clone(); //判断对象是否为同一个对象 System.out.println("DeepClone是否为同一个对象:"+(dc == dcc)); System.out.println("DeepClone:list是否为同一个对象:"+(dc.getList() == dc.getList())); } }
输出结果:
DeepClone是否为同一个对象:false DeepClone:list是否为同一个对象:true
修改代码实现深克隆:
在DeepClone.java中修改clone()方法:
/* * 实现的克隆方法 */ public Object clone(){ try{ /* * 常用的克隆调用方法 */ DeepClone dc = (DeepClone)super.clone(); dc.setList(new ArrayList<SomeThing>()); for(SomeThing someThing : list){ dc.getList().add((SomeThing)someThing.clone()); } return dc; }catch(CloneNotSupportedException e){ return null; } }
在SomeThing.java中增加了clone方法:
/* * 实现的克隆方法 */ public Object clone(){ try{ /* * 常用的克隆调用方法 */ return super.clone(); }catch(CloneNotSupportedException e){ e.printStackTrace(); return null; } }
输出结果:
DeepClone是否为同一个对象:false DeepClone:list是否为同一个对象:true
注:实现了深克隆 |