2、如何实现深克隆
还是上面的例子,我们改下代码
class Model2 implements Cloneable{ int height; @Override public Object clone() throws CloneNotSupportedException { System.out.println("clone Model2"); return super.clone(); } } public class CloneModel implements Cloneable{ private String name; private int age; private Model2 model2; public CloneModel() { this.model2 = new Model2(); } public Model2 getModel2() { return model2; } public void setModel2(Model2 model2) { this.model2 = model2; } @Override public CloneModel clone() throws CloneNotSupportedException { CloneModel cloneModelTemp = (CloneModel)super.clone(); cloneModelTemp.setModel2((Model2)cloneModelTemp.getModel2().clone()); return cloneModelTemp; } @Override public String toString() { return "CloneModel{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
再次测试下
public static void main(String[] args) throws CloneNotSupportedException { CloneModel cloneModel1 = new CloneModel(); CloneModel cloneModel2 = cloneModel1.clone(); System.out.println(cloneModel1.getModel2()==cloneModel2.getModel2()); }
输出
false
这么做就要在super.clone的基础上 继续对非基本类型的对象递归的再次clone。显然这么方式是繁琐的且不可靠的。有没有其他的方式呢?序列化
3、序列化实现深度克隆
(1)使用java自身的序列化转为二进制数 ,再反序列化为对象
上面的例子改造下
import java.io.Serializable; class Model2 implements Serializable { int height; } public class CloneModel implements Serializable { private String name; private int age; private Model2 model2; public CloneModel() { this.model2 = new Model2(); } public Model2 getModel2() { return model2; } }
测试代码
import com.yangfei.test.CloneModel; import java.io.*; public class YfTest { public static <T extends Serializable> T deepCloneObject(T object) throws IOException { T deepClone = null; ObjectInputStream ois = null; try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); ) { oos.writeObject(object); ByteArrayInputStream bais = new ByteArrayInputStream(baos .toByteArray()); ois = new ObjectInputStream(bais); deepClone = (T)ois.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } finally { if(ois != null){ ois.close(); } } return deepClone; } public static void main(String[] args) throws IOException { CloneModel cloneModel1 = new CloneModel(); CloneModel cloneModel2 = deepCloneObject(cloneModel1); System.out.println(cloneModel1.getModel2()==cloneModel2.getModel2()); } }
输出
false
(2)其他序列化方式,如对象序列化json字符串再反序列化为对象
我们使用google的gson来进行序列化,上代码
import com.google.gson.Gson; import java.io.Serializable; class Model2 implements Serializable { int height; } public class CloneModel implements Serializable { private String name; private int age; private Model2 model2; public CloneModel() { this.model2 = new Model2(); } public Model2 getModel2() { return model2; } public CloneModel deepClone() { Gson gson = new Gson(); return gson.fromJson(gson.toJson(this), CloneModel.class); } }
测试代码
public static void main(String[] args) throws IOException { CloneModel cloneModel1 = new CloneModel(); CloneModel cloneModel2 = cloneModel1.deepClone(); System.out.println(cloneModel1.getModel2()==cloneModel2.getModel2()); }
输出
false
(3)性能对比测试
上代码
public static void main(String[] args) throws IOException { CloneModel cloneModel1 = new CloneModel(); long time1 = System.currentTimeMillis(); for(int i=0;i<1000;i++){ // CloneModel cloneModel2 = cloneModel1.deepClone(); CloneModel cloneModel2 = deepCloneObject(cloneModel1); } long time2 = System.currentTimeMillis(); System.out.println((time2-time1)+"ms"); }