Java深拷贝与浅拷贝详解:实现原理与代码示例

在Java编程中,对象复制是一个常见的操作。理解深拷贝和浅拷贝的区别对于编写健壮的代码至关重要。本文将详细介绍这两种拷贝方式,并提供代码示例以帮助您更好地理解。

1. 浅拷贝 (Shallow Copy)

浅拷贝是指创建一个新对象,但新对象内部的引用类型属性仍然指向原始对象的属性。换句话说,浅拷贝只复制对象本身和基本数据类型,而对于引用类型属性,只是复制了它们的引用,并没有创建新的对象。

浅拷贝的特点:

  • 创建新对象的速度较快,因为只复制了引用。* 修改新对象的引用类型属性会影响原对象的对应属性,因为它们指向同一个对象。

实现浅拷贝的方式:

  • 使用 Object 类的 clone() 方法。

**示例代码:**javaclass Person implements Cloneable { private String name; private int age;

public Person(String name, int age) {        this.name = name;        this.age = age;    }

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

public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person('Alice', 20); Person p2 = (Person) p1.clone(); System.out.println(p1 == p2); // false System.out.println(p1.equals(p2)); // true }}

2. 深拷贝 (Deep Copy)

深拷贝是指创建一个新对象,并递归地复制所有引用类型属性,包括嵌套的对象。这意味着新对象和原对象拥有完全独立的属性,修改其中一个不会影响另一个。

深拷贝的特点:

  • 创建新对象的速度较慢,因为需要递归地复制所有属性。* 修改新对象的属性不会影响原对象的对应属性,因为它们是完全独立的对象。

实现深拷贝的方式:

  • 序列化与反序列化: 通过实现 Serializable 接口,将对象序列化到字节流,然后再反序列化为新的对象。* 手动复制: 为每个需要深拷贝的类编写自定义的复制方法,递归地复制所有引用类型属性。

**示例代码 (序列化与反序列化):**javaimport java.io.*;

class Person implements Serializable { private String name; private int age;

public Person(String name, int age) {        this.name = name;        this.age = age;    }

public Person deepClone() 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();    }}

public class Main { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p1 = new Person('Alice', 20); Person p2 = p1.deepClone(); System.out.println(p1 == p2); // false System.out.println(p1.equals(p2)); // false }}

注意:

  • 要实现深拷贝,需要确保对象及其所有引用类型属性都实现了 Serializable 接口,否则会抛出 NotSerializableException 异常。

总结

选择使用哪种拷贝方式取决于具体的需求。如果只是需要复制对象的结构而不关心属性值的独立性,则可以使用浅拷贝。如果需要创建完全独立的对象副本,则应该使用深拷贝。


原文地址: https://www.cveoy.top/t/topic/fK74 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录