【大白话说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)机制。
  • 面试官可能会追问"浅拷贝有哪些局限性?"答:浅拷贝可能导致多个对象共享同一引用类型的成员变量,修改一个对象会影响其他对象。
相关推荐
mldong1 小时前
给若依加审批流,不用 Flowable
java·spring boot·架构
考虑考虑3 小时前
数据库中的EXISTS
运维·数据库·后端
Wang's Blog3 小时前
Java框架快速入门: Spring Security+OAuth2之数据库和实体类的RBAC改造
java·数据库·spring
找方案3 小时前
AI+人力资源:AI招聘面试的兴起与争议
人工智能·面试·职场和发展
讳疾忌医丶3 小时前
深度拆解 RocksDB 内核:基于 C++17 的 FIFO 调度状态机与温度阶梯自愈设计
java·c++·算法·架构
lsswear4 小时前
Python 并发 线程
开发语言·python
郑州光合科技余经理4 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
毅炼4 小时前
Rover-Suite 开源发布:轻量服务注册中心与网关一体化方案
java·后端·系统架构·gateway
软件课代表CiCi4 小时前
运行库是什么?电脑缺运行库怎么办?c++运行库缺失修复全攻略
开发语言·c++·windows·电脑·dll修复·dll丢失·运行库
梦想平凡4 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理