Java 中的深拷贝与浅拷贝

时间:2020-12-22 19:54:35

clone() 是 Object 类的一个 protected 方法,如果一个类想要使用 clone() 这个方法,需要实现 Cloneable 接口,并 Override clone()(需要自己定义 clone 规则)

所谓浅拷贝,就是指 Class_A 实现了 Cloneable 接口,并重写了 clone()方法,但是 Class_A 中的引用类型成员变量 ref_b 所指向的类 Class_B 没有实现 Cloneable 接口

Class Class_A implements Cloneable {
    public Class_B ref_b;

    @Override
    public Object clone(){
    ......
    }
}

Class Class_B {
    public xxx;
}

public static void main(){
    Class_A obj_a_1 = new Class_A();
    Class_A obj_a_2 = (Class_A) obj_a_1.clone();
}

obj_a_1 和 obj_a_2 虽然指向了不同的对象,但是两者的成员变量 ref_b 却指向了相同的对象(JVM中相同的堆地址)


所谓浅拷贝,就是指 Class_A 实现了 Cloneable 接口,并重写了 clone()方法,但是 Class_A 中的引用类型成员变量 ref_b 所指向的类 Class_B 也实现了 Cloneable 接口,并重写了 clone()方法

Class Class_A implements Cloneable {
    public Class_B ref_b;

    @Override
    public Object clone(){
    ......
    }
}

Class Class_B implements Cloneable {
    public xxx;

    @Override
    public Object clone(){
    ......
    }
}

public static void main(){
    Class_A obj_a_1 = new Class_A();
    Class_A obj_a_2 = (Class_A) obj_a_1.clone();
}

此时 obj_a_1 和 obj_a_2 指向了不同的对象,而且两者的成员变量 ref_b 指向了不同的对象(JVM中不同的堆地址)


另一个实现拷贝的方法是 类 实现 Serializable 接口,类中的 引用类型 的成员变量 所对应的 类 也要实现 Serializable 接口,然后通过将 类实例 写入流,并从流中读取出来的方式进行(深)拷贝

public class ObjCloner {

    @SuppressWarnings("unchecked")
    public static  <T>T cloneObj(T obj){

        T retVal = null; 

        try{

            // 将对象写入流中
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);


            // 从流中读出对象
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream  ois = new ObjectInputStream(bais);

            retVal = (T)ois.readObject();

        }catch(Exception e){
            e.printStackTrace();
        }

        return retVal;
    }

参考资料:

1。java提高篇(六)—–使用序列化实现对象的拷贝
https://www.cnblogs.com/chenssy/p/3382979.html

2、Java 深拷贝和浅拷贝
https://www.cnblogs.com/mengdd/archive/2013/02/20/2917971.html

3、一看就懂的,java深拷贝浅拷贝
https://blog.csdn.net/XIAXIA__/article/details/41652057