Java浅拷贝和深拷贝方法

在Java中,对象的拷贝是一个常见的操作。拷贝操作可以分为浅拷贝和深拷贝两种。这两种拷贝方式在使用时有不同的应用场景和效果。本文将介绍Java中浅拷贝和深拷贝的概念、区别以及如何实现。

浅拷贝和深拷贝的概念

浅拷贝

浅拷贝是指将一个对象的值复制到另一个对象中,但是只复制对象本身和对象的所有引用,不会复制对象引用的对象。也就是说,浅拷贝只是拷贝了对象的引用,而不是对象本身。如果原对象中包含引用类型的属性,那么浅拷贝后的对象和原对象会共享相同的引用对象。

深拷贝

深拷贝是指将一个对象的值以及对象引用的对象都复制到另一个对象中,即递归复制对象的所有引用对象。深拷贝会创建一个新的对象,其属性值和引用对象均与原对象完全独立,不会共享任何引用对象。

浅拷贝和深拷贝的区别

  1. 共享引用对象的不同表现: 浅拷贝后的对象会共享原对象引用对象的引用,而深拷贝后的对象会拥有独立的引用对象。
  2. 嵌套对象的处理: 浅拷贝只会复制对象的引用,而深拷贝会递归复制对象的所有引用对象。
  3. 性能开销: 深拷贝通常会比浅拷贝消耗更多的系统资源和时间,因为需要复制对象的所有引用对象。

浅拷贝和深拷贝的实现

浅拷贝实现

在Java中,实现对象的浅拷贝可以通过clone()方法或者实现Cloneable接口来实现。下面是一个使用clone()方法实现对象浅拷贝的示例代码:

public class Student implements Cloneable {
    private String name;
    private int age;

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static void main(String[] args) {
        Student student1 = new Student("Alice", 20);
        try {
            Student student2 = (Student) student1.clone();
            System.out.println(student2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

深拷贝实现

实现对象的深拷贝可以通过序列化和反序列化、递归复制对象的方式实现。下面是一个使用序列化和反序列化实现对象深拷贝的示例代码:

import java.io.*;

public class Address implements Serializable {
    private String city;

    public Address(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                '}';
    }
}

public class Student implements Serializable {
    private String name;
    private int age;
    private Address address;

    public Student(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Student deepCopy() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (Student) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }

    public static void main(String