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(); }}
浅拷贝适用场景:
对象无引用类型属性或无需独立修改。
追求性能且可接受副作用。
深拷贝适用场景:
对象包含引用类型属性且需完全隔离。
代码可维护性和正确性优先。
通过理解两者差异及实现方式,可更精准地选择克隆策略,提升代码质量。