Java中对象克隆浅拷贝和深拷贝的区别?

Java中对象克隆浅拷贝和深拷贝的区别?
最新回答
残●沐伊丶

2021-12-26 21:55:31

Java中对象克隆的浅拷贝仅复制对象引用,深拷贝则创建完全独立的新对象。 以下是具体区别及实现方式:

核心区别
  • 浅拷贝

    创建新对象,但新对象的引用类型属性仍指向原对象属性的内存地址。

    修改新对象的引用类型属性会影响原对象。

    适用于简单对象(属性均为基本类型)。

    示例:通过clone()方法实现时,默认行为为浅拷贝。

    class Person { String name; List<String> hobbies; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); // 浅拷贝 }}// 修改拷贝对象的hobbies会影响原对象
  • 深拷贝

    创建新对象,并递归复制所有属性(包括引用类型属性)。

    新对象与原对象完全独立,修改互不影响。

    适用于复杂对象(包含引用类型属性)。

    示例:手动递归复制或序列化实现。

    class Person { public Person deepCopy() { List<String> copiedHobbies = new ArrayList<>(this.hobbies); // 深拷贝hobbies return new Person(this.name, copiedHobbies); }}// 修改拷贝对象的hobbies不会影响原对象
实现方式对比
  • 浅拷贝实现

    直接调用Object.clone()(需实现Cloneable接口)。

    仅复制对象本身,不处理引用类型属性。

  • 深拷贝实现

    手动递归复制:逐层复制引用类型属性。class Person { public Person deepCopy() { List<String> newHobbies = new ArrayList<>(); for (String hobby : this.hobbies) { newHobbies.add(hobby); // 复制每个元素 } return new Person(this.name, newHobbies); }}

    序列化/反序列化:通过字节流创建独立对象。import java.io.*;class Person implements Serializable { public Person deepCopy() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (Person) ois.readObject(); }}

选择策略
  • 浅拷贝适用场景

    对象无引用类型属性或无需独立修改。

    追求性能且可接受副作用。

  • 深拷贝适用场景

    对象包含引用类型属性且需完全隔离。

    代码可维护性和正确性优先。

注意事项
  • 序列化限制:需确保所有类实现Serializable接口,且处理异常。
  • 性能权衡:深拷贝可能增加内存和计算开销。
  • 循环引用:手动递归时需避免对象间的循环引用导致栈溢出。

通过理解两者差异及实现方式,可更精准地选择克隆策略,提升代码质量。