package com.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import com.pojo.A;
public class Test2 implements Cloneable,Serializable {
int b=50;
private A a=new A(100);
public Object deepclone() {
ObjectOutputStream os=null;
ObjectInputStream is=null;
ByteArrayOutputStream bos=new ByteArrayOutputStream();
Object target=null;
try {
os=new ObjectOutputStream(bos);
os.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
is = new ObjectInputStream(bis);
target = is.readObject();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return target;
}
public static void main(String[] args)throws CloneNotSupportedException {
Test2 test2=new Test2();
Test2 test22=(Test2) test2.clone();
test2.b=39;//不能改变原来的值
test22.b=80;
System.out.println(test2.b);
System.out.println(test22.b);//是基本数据类型或者String类型,都是深度克隆
test2.a.setA(200);
test22.a.setA(300);
System.out.println(test2.a);
System.out.println(test22.a);//是浅度克隆,对象是指向的同一个
Test2 test23=(Test2)test2.deepclone();
test23.a.setA(90);
System.out.println(test23.a);
System.out.println(test2.a);//深度克隆,对象不是同一个
}
}
运行结果如下
39
80
com.pojo.A@7ba28183
com.pojo.A@7ba28183
com.pojo.A@2ea0eb2a
com.pojo.A@7ba28183
深拷贝的实现方法主要有两种:
一、通过重写clone方法来实现深拷贝
与通过重写clone方法实现浅拷贝的基本思路一样,只需要为对象图的每一层的每一个对象都实现Cloneable接口并重写clone方法,最后在最顶层的类的重写的clone方法中调用所有的clone方法即可实现深拷贝。简单的说就是:每一层的每个对象都进行浅拷贝=深拷贝。
二、通过对象序列化实现深拷贝(上面的例子就是序列化 写在流中)
虽然层次调用clone方法可以实现深拷贝,但是显然代码量实在太大。特别对于属性数量比较多、层次比较深的类而言,每个类都要重写clone方法太过繁琐。
将对象序列化为字节序列后,默认会将该对象的整个对象图进行序列化,再通过反序列即可完美地实现深拷贝。