【大白话说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)机制。
  • 面试官可能会追问"浅拷贝有哪些局限性?"答:浅拷贝可能导致多个对象共享同一引用类型的成员变量,修改一个对象会影响其他对象。
相关推荐
yaoxin52112319 小时前
502. Java 反射 - 编写 MessageInterceptor 类
java·开发语言
wuyk55519 小时前
Python零基础入门第五章:元组Tuple(不可变容器详解、列表与元组区别)
开发语言·python
风流 少年19 小时前
Spring AI 2.0:阿里云百炼平台(工作流应用)
java·后端·spring
长谷深风11119 小时前
AI Tool 设计:粒度、参数与错误恢复怎么做
java·大数据·人工智能·ai agent·agent工作流·智能体设计·ai产品设计
2601_9657984719 小时前
Build a Fast, High-Ranking Restaurant Website with Rolanda Theme
开发语言·ios·swift
__zRainy__19 小时前
Node系列 · 数据库:单表查询
数据库·后端·mysql·node.js
caimouse19 小时前
ReactOS 窗口系统分析(25):标题栏显示与系统按钮 — nonclient.c 标题栏专题
c语言·开发语言
诺伦19 小时前
Rust 错误处理实战:从 unwrap 到优雅 Result 的进阶之路
开发语言·后端·rust
caimouse20 小时前
ReactOS 窗口系统分析(14):计时器/属性/加速键/热键 — timer.c + prop.c + accelerator.c + hotkey.c
c语言·开发语言·reactos
circuitsosk20 小时前
Python 模块与包管理:import 机制、虚拟环境与 pip 完全指南
开发语言·python·pip·依赖管理·模块与包