【大白话说Java面试题】【Java基础篇】第40题:Java中的深拷贝和浅拷贝有什么区别?

0 阅读2分钟

📌 专栏:大白话说Java面试题 — 01-Java基础篇

第40题:Java中的深拷贝和浅拷贝有什么区别

📚 回答:

  • 核心概念
    深拷贝和浅拷贝是 Java 中对象复制的两种方式,主要区别在于是否复制对象内部的引用类型成员变量。

1. 浅拷贝
  • 定义

    • 浅拷贝只复制对象本身,而不复制对象内部的引用类型成员变量。
    • 复制后的对象和原对象共享引用类型的成员变量。
  • 实现方式

    • 实现 Cloneable 接口并重写 clone() 方法。
    • 默认的 clone() 方法执行的是浅拷贝。

    💡 代码示例
    以下代码展示了浅拷贝的行为:

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

class Person implements Cloneable {
    String name;
    Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 默认浅拷贝
    }
}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("Beijing");
        Person p1 = new Person("Alice", address);
        Person p2 = (Person) p1.clone();

        p2.address.city = "Shanghai";
        System.out.println(p1.address.city); // 输出 Shanghai
    }
}

2. 深拷贝
  • 定义

    • 深拷贝不仅复制对象本身,还递归地复制对象内部的所有引用类型成员变量。
    • 复制后的对象和原对象完全独立,互不影响。
  • 实现方式

    • clone() 方法中手动复制引用类型成员变量。
    • 或者通过序列化(Serializable)实现深拷贝。

    💡 代码示例
    以下代码展示了深拷贝的行为:

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

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

class Person implements Cloneable {
    String name;
    Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = (Address) address.clone(); // 深拷贝引用类型
        return cloned;
    }
}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("Beijing");
        Person p1 = new Person("Alice", address);
        Person p2 = (Person) p1.clone();

        p2.address.city = "Shanghai";
        System.out.println(p1.address.city); // 输出 Beijing
    }
}

3. 对比总结
特性浅拷贝深拷贝
复制范围只复制对象本身复制对象及其所有引用类型成员变量
实现方式默认 clone() 方法手动复制引用类型或序列化
适用场景引用类型成员变量无需独立时引用类型成员变量需要完全独立时

💡 面试官视角

  • 面试官可能会问“如何实现深拷贝?”答:可以通过手动复制引用类型成员变量或使用序列化(Serializable)机制。
  • 面试官可能会追问“浅拷贝有哪些局限性?”答:浅拷贝可能导致多个对象共享同一引用类型的成员变量,修改一个对象会影响其他对象。