Java中的深拷贝与浅拷贝
字数 539 2025-11-04 08:34:41

Java中的深拷贝与浅拷贝

一、概念描述
深拷贝和浅拷贝是对象复制的两种方式。浅拷贝只复制对象本身和其基本类型字段,但引用类型字段仍指向原对象的引用地址;深拷贝则会递归复制所有引用类型字段指向的对象,创建一个完全独立的新对象。

二、浅拷贝详解

  1. 实现方式

    • 实现Cloneable接口
    • 重写Object.clone()方法(默认为protected)
    • 调用super.clone()完成基础复制
  2. 代码示例

class Person implements Cloneable {
    String name;
    Address address; // 引用类型字段
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝
    }
}
  1. 问题演示
Person p1 = new Person("Tom", new Address("北京"));
Person p2 = (Person) p1.clone();
p2.address.city = "上海"; // p1的address也会被修改!
System.out.println(p1.address.city); // 输出"上海"

三、深拷贝实现方式

  1. 手动递归克隆
class Address implements Cloneable {
    String city;
    // 重写clone方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable {
    String name;
    Address address;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = (Address) this.address.clone(); // 关键步骤
        return cloned;
    }
}
  1. 序列化方式
public class DeepCopyUtil {
    public static <T> T deepCopy(T obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(obj);
        
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (T) ois.readObject();
    }
}
// 要求所有涉及类实现Serializable接口

四、对比总结

特性 浅拷贝 深拷贝
对象独立性 部分独立 完全独立
引用类型处理 共享引用 创建新对象
性能开销 大(尤其序列化方式)
实现复杂度 简单 复杂

五、注意事项

  1. 循环引用问题:深拷贝时需要处理对象间的循环引用
  2. 性能考虑:对于复杂对象图,深拷贝可能带来较大开销
  3. 推荐方案:考虑使用不可变对象避免拷贝需求,或使用拷贝构造器替代Cloneable接口

六、实际应用场景

  • 浅拷贝:配置对象共享基础配置时
  • 深拷贝:需要完全隔离的上下文环境(如会话复制、事务回滚)
Java中的深拷贝与浅拷贝 一、概念描述 深拷贝和浅拷贝是对象复制的两种方式。浅拷贝只复制对象本身和其基本类型字段,但引用类型字段仍指向原对象的引用地址;深拷贝则会递归复制所有引用类型字段指向的对象,创建一个完全独立的新对象。 二、浅拷贝详解 实现方式 实现 Cloneable 接口 重写 Object.clone() 方法(默认为protected) 调用 super.clone() 完成基础复制 代码示例 问题演示 三、深拷贝实现方式 手动递归克隆 序列化方式 四、对比总结 | 特性 | 浅拷贝 | 深拷贝 | |------|--------|--------| | 对象独立性 | 部分独立 | 完全独立 | | 引用类型处理 | 共享引用 | 创建新对象 | | 性能开销 | 小 | 大(尤其序列化方式) | | 实现复杂度 | 简单 | 复杂 | 五、注意事项 循环引用问题:深拷贝时需要处理对象间的循环引用 性能考虑:对于复杂对象图,深拷贝可能带来较大开销 推荐方案:考虑使用不可变对象避免拷贝需求,或使用拷贝构造器替代Cloneable接口 六、实际应用场景 浅拷贝:配置对象共享基础配置时 深拷贝:需要完全隔离的上下文环境(如会话复制、事务回滚)