关于Java对象的深拷贝和浅拷贝的概念与区别

时间:2023-03-23
类别:教程 - 网页设计
深拷贝和浅拷贝是关于对象拷贝的概念,用于描述在复制一个对象时,复制的是对象本身还是对象的引用,从而影响到新旧对象之间的关系。

浅拷贝是指将一个对象复制一份,但是新旧对象共享同一个引用,也就是说新对象和旧对象指向同一块内存地址,对新对象的修改会影响到旧对象。而深拷贝是指将一个对象复制一份,并且新对象和旧对象是完全独立的,互不干扰,对新对象的修改不会影响到旧对象。

在Java中,实现浅拷贝可以通过Object类的clone()方法实现,因为Object类中的clone()方法是浅拷贝的,但是需要实现Cloneable接口才能使用。而实现深拷贝需要自己编写代码,可以使用序列化和反序列化来实现深拷贝。

下面是Java代码实现深拷贝的示例:

javaCopy code
import 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 String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    // 实现深拷贝
    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();
    }
}
 
public class DeepCopyExample {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person p1 = new Person("Tom", 20);
        Person p2 = p1.deepCopy();
 
        System.out.println(p1 == p2); // false
        System.out.println(p1.getName() == p2.getName()); // false
    }
}

在上面的示例中,我们使用了Java的序列化和反序列化来实现深拷贝。首先将对象写入一个字节数组输出流中,然后将字节数组输出流中的字节数组读取到一个字节数组输入流中,最后使用对象输入流读取字节数组输入流中的字节序列并返回新的对象。由于对象序列化和反序列化过程中会创建新的对象,因此返回的新对象是深拷贝的结果。

要使用Java实现浅拷贝,可以使用Java提供的clone()方法来复制一个对象。该方法会创建一个新对象,其中包含原始对象的所有字段和属性,但是它们的值只是复制了引用,而不是创建新的对象。

下面是一个示例代码,展示了如何使用Java的clone()方法来实现浅拷贝:

javaCopy code
class Person implements Cloneable {
    public String name;
    public int age;
    public List<String> hobbies;
 
    public Person(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }
 
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
 
// 使用示例
Person person1 = new Person("Tom", 20, Arrays.asList("reading", "swimming"));
Person person2 = (Person) person1.clone();
 
// person1和person2是两个不同的对象,但是它们的属性值相同
System.out.println(person1.name.equals(person2.name)); // true
System.out.println(person1.age == person2.age); // true
System.out.println(person1.hobbies == person2.hobbies); // true,浅拷贝只是复制了引用

需要注意的是,要实现clone()方法,必须实现Cloneable接口。此外,Java中的浅拷贝只能复制对象的基本数据类型和引用类型,而不能复制对象的内部对象。如果需要实现深拷贝,则需要自己编写代码来复制对象的所有属性,包括内部对象。

    收藏