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

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

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

📚 回答:

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

1. 浅拷贝
  • 定义

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

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

    💡 代码示例

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

java 复制代码
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)实现深拷贝。

    💡 代码示例

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

java 复制代码
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)机制。
  • 面试官可能会追问"浅拷贝有哪些局限性?"答:浅拷贝可能导致多个对象共享同一引用类型的成员变量,修改一个对象会影响其他对象。
相关推荐
@小匠1 小时前
云之家表单数据解析 skills (yzj-form-parser)
java
云烟成雨TD1 小时前
Spring AI Alibaba 1.x 系列【48】状态图编译配置类:CompileConfig 源码解析
java·人工智能·spring
xh didida2 小时前
算法 -- 位运算
开发语言·c++·算法
谙弆悕博士2 小时前
快速学C语言——第2章:编程规范与代码风格
服务器·c语言·开发语言·经验分享·程序人生·学习方法·业界资讯
byzh_rc2 小时前
[AI编程从入门到入土] 装饰器decorator
开发语言·python·ai编程
贫民窟的勇敢爷们2 小时前
Java 与 Python 如何选型与融合
java·开发语言·python
流氓也是种气质 _Cookie2 小时前
Chrome Performance常见名词解释(FP, FCP, LCP, DCL, FMP, TTI, TBT, FID, CLS)
开发语言·javascript·ecmascript
gihigo19982 小时前
基于MATLAB的LTE物理层仿真系统
开发语言·matlab
小强19882 小时前
为什么你建了索引,查询还是很慢?常见失效原因汇总
后端