Java中对象的浅拷贝和深拷贝

February 28, 2024 作者: yijianhao 分类: java 浏览: 66 评论: 0

在Java中,对象的浅拷贝和深拷贝主要涉及对象内存中的复制方式。

浅拷贝(Shallow Copy):

  • 只复制对象的基本数据类型的值,以及对象的引用类型变量的引用但不复制引用对象本身。
  • 实现方式通常是通过对象的clone()方法,如果要使用这种方式,需要实现Cloneable接口并重写clone()方法。
  • 浅拷贝会导致新对象中的引用类型变量和原始对象中的引用类型变量指向同一个实例。

深拷贝(Deep Copy):

  • 复制对象的所有基本数据类型的值,以及引用类型的“内容”,而不是引用。
  • 实现方式可以通过重写clone()方法并手动复制其内部的引用对象,或者通过序列化(实现Serializable接口,通过对象流进行读写来实现深拷贝)。
  • 深拷贝会创建被引用对象的新副本,因此新对象与原始对象不会共享状态。

简单示例代码:

浅拷贝:

public class ShallowCopy implements Cloneable {
    private int[] data;

    public ShallowCopy(int[] data) {
        this.data = data;
    }

    public int[] getData() {
        return data;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

深拷贝:

import java.io.*;

public class DeepCopy implements Serializable {
    private int[] data;

    public DeepCopy(int[] data) {
        this.data = data;
    }

    public int[] getData() {
        return data;
    }

    public DeepCopy deepCopy() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (DeepCopy) ois.readObject();
        } 
        catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
}

或者可以使用深拷贝的工具类

import java.io.*;

public class DeepCopyUtil {

    /**
     * 深拷贝方法
     * @param object 要进行深拷贝的对象,必须实现Serializable接口
     * @return 深拷贝后的对象
     */
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T deepCopy(T object) {
        T deepCopyObject = null;
        try {
            // 将对象写入流中
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.flush();

            // 从流中读出对象
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            deepCopyObject = (T) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return deepCopyObject;
    }
}

评论