惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
P
Privacy International News Feed
T
Tenable Blog
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
S
Securelist
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
月光博客
月光博客
T
The Blog of Author Tim Ferriss
Scott Helme
Scott Helme
爱范儿
爱范儿
Stack Overflow Blog
Stack Overflow Blog
C
Cisco Blogs
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
Security Latest
Security Latest
Blog — PlanetScale
Blog — PlanetScale
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
博客园 - 三生石上(FineUI控件)
I
InfoQ
Spread Privacy
Spread Privacy
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
A
About on SuperTechFans
博客园_首页
Engineering at Meta
Engineering at Meta
Project Zero
Project Zero
Latest news
Latest news

码云笔记

Pinia v4 发布:Vue 状态管理进入新时代 Linux LVM:故障排查与数据恢复指南 Java中wait()与sleep()方法的不同点是什么? Bonsai27B 重磅落地!27B 大模型实现手机本地运行 ES2026 第 17 版新增的 5 个新特性 高德重磅上线 ABot‑World Studio,消费级显卡就能搭建专属 3D 虚拟世界 Java中final、finally和finalize的区别是什么? 怎么修改Ollama及其模型的默认路径?Ollama路径修改、迁移与重启的操作教程 iOS27 公开测试版正式上线!AI Siri 与液态玻璃成最大看点 Yuku正式发布!比 Vite+ 快 5.4 倍的前端工具链 Linux lsof 命令详解:进程与文件监控实战 Claude Code CLI命令手册 代码审查重构Bug修复场景化工作流 OpenClaw中连接并使用本地Ollama模型的操作教程 GPT-5.6 今天正式上线:OpenAI 掏出”太阳系”全家桶,Sol / Terra / Luna 齐发,打的却是一张”效率牌” Nacos MySQL持久化部署完整教程 GPT-5.6系列正式上线:OpenAI以效能与性价比重塑AI行业竞争格局 Java中序列化与反序列化的概念是什么? 如何在HTML中实现字体颜色根据背景自动变化? JDK动态代理与CGLIB动态代理的区别是什么? OpenClaw数据加密敏感信息保护的完整教程 砸超亿美元算力!亚马逊秘密启动Moonraker项目,Alexa迎来颠覆性升级 PHP 最轻量、结构化 .docx 到 Markdown 转换器 Elephant TypeScript 7.0 正式发布 蚂蚁灵波开源全球首款 MoE 具身视频大模型 LingBot-Video,为机器人世界模型搭建新底座 SpaceX AI联合Cursor推出Grok 4.5 搅动专业AI赛道格局 英伟达Vera CPU落地商用,改写AI代理时代算力竞争规则 什么是端点检测与响应(EDR)以及它的工作原理介绍 Anime.js 已经 10 岁了!作者查出脑瘤,V5 将开始收费! 星链开启全面升级!SpaceX申请十万颗卫星,构建AI时代全球天基基建 PHP 通用表达式语言 CEL-PHP 2.0.0 正式发布! WordPress 7.0 下载,支持AI建站 Docker Desktop(windows)版本下载 详解 Linux 端口监听检查工具:ss、netstat、lsof 京东 JoyAI 上线 UGC 数字人功能,普通人一键打造专属虚拟分身 Java中Integer缓存池的作用是什么? 应对劳动力短缺 日本加码布局AI机器人产业,2040年拟千万台机器人落地各行各业 Claude旗舰模型收费规则大变:订阅权益取消,转为按量计费 MySQL中的分布式架构和复制策略 如何在 MySQL 中处理 BLOB 和 CLOB 数据类型? 如何在 MySQL 中处理和优化长时间运行的查询? git提交信息分别用什么icon好? Composer安装与配置教程 35岁华为员工偷偷面试,被面试官嘲讽:你是被淘汰的吧?他的回怼让面试官当场闭嘴 谷歌Nano Banana 2 Lite正式上线:4秒极速出图,大幅降低AI生图成本 锐捷交换机运维配置完全参考手册 Vue 3.5:Effect Scope 与响应式污染隔离机制 IS-IS协议基本概念、工作原理与扩展应用 美团LongCat-2.0重磅开源!国产万亿参数大模型解锁超长上下文新能力 LangChain4j 和 LangGraph4j 区别是什么?哪个更好? Claude Code 的聊天和配置可以一键搬进 Codex 了 码云笔记详解Markdown格式兼容性、图片显示失效与同步冲突解决 python实现自动爬取某论坛帖子并导出到Word文档的实战教程 高德低调内测 AI 零代码工具“袋马”,切入小微商家轻量化应用开发赛道 一文看懂OSPF:基础概念、工作原理和应用场景 PHP (Yii2) 接入企业级 SSO 单点登录实战教程 Google终于支持修改Gmail邮箱了?实测告诉你哪些能改,哪些不能改!(附详细教程+FAQ) UCloud 4.6 元 / 月服务器是真的吗? 2026 云服务器完整选购攻略 Webiny:无服务器应用程序框架 Fyrox:现代化的 Rust 游戏引擎 千问发布全球首个原生语言世界模型Qwen-AgentWorld,AI智能体迈入全环境实操新时代 火山引擎上新豆包音频生成模型1.0,AI音频生成实现一键全流程创作 使用Claude Code经常遇到的10个问题 如何批量清理wordpress所有文章和标签,保留设置,保留分类? 谷歌 NotebookLM 内测文献综述矩阵工具,Gemini3.5 赋能 AI 学术结构化研究 京东开源JoyAI-VL-Interaction模型 解锁AI实时视频视觉交互新形态 破解中小商家海报设计难题!MeiGen-AI开源闭环AI设计方案落地 详解Bash set 命令:set -e、set -x 和 set -u 完全指南 Node Plus ?比 pnpm 快 24 倍! Plan-Execute-Replan 和 ReAct 的区别是什么? Anthropic最新报告揭秘:AI编程人机协作成开发者主流工作模式 详解PostgreSQL 18 逻辑复制冲突检测与解决方法 JDK动态代理与CGLIB动态代理的区别是什么? 详解 Linux 中 localhost、127.0.0.1 与 Loopback(回环地址) OpenAI Codex新手入门教程 安装配置AGENTS.md与MCP全流程详解 程序员必备AGENTS.md配置指南 规避AI编码修改乱象 使用 Codex 必装的 12 个插件,你值得拥有! macOS AI CLI工具安装与避坑指南 OpenClaw Gemini Claude报错全套解决方案 智谱AI正式开源GLM-5. 2 模型:主打1M无损上下文与长程代码任务 小米 MiMo Claw 正式版上线 轻量化 Agent 打通金山办公生态 如何定义 Vue 的动态路由?如何获取传过来的动态参数? 记录Claude Code Router 接入过程遇到问题及解决方法 千问AI眼镜凭硬核实力领跑2026智能穿戴赛道 程序员特有的习惯你占了几条! 郝景芳新作半数内容由AI创作,文坛郝景芳AI写作争议再起 使用 iftop、nload、bmon、vnstat 监控 Linux 网络带宽 现代富文本编辑器为什么最终都会抛弃 DOM? Vue 的 v-cloak 和 v-pre 指令有什么作用? 去哪里买抖音号?抖音小号在线购买-抖音小号出售批发 实名闲鱼小号出售|闲鱼账号批发|咸鱼发布账号|出售闲鱼发布账号 zfb号购买-支付宝小号购买-实名支付宝购买号-企业支付宝购买-支付宝小号批发 个人支付宝实名账号出售|v2/v3支付宝账号出售|实名支付宝小号购买 闲鱼账号哪里有卖-闲鱼实名账号购买的途径 Java注解的实现原理是什么? Agentation MemPalace 《置身钉内》之好词好句好段摘抄 AI有声书革命!万象有声全自动生产线,7元/万字颠覆网文有声化行业 详解CentOS 7跨版本迁移Rocky Linux9 生产环境安全升级教程 Java中序列化与反序列化的含义是什么? 18. Python 标准库之 Json 模块
Java中深拷贝与浅拷贝的区别是什么?
不良 普通 · 2026-07-06 · via 码云笔记

AI 概述

本文讲解Java浅、深拷贝原理与代码示例:浅拷贝仅复制基础类型,引用对象共享内存,修改会互相影响;深拷贝递归复制所有引用对象,二者完全隔离。对比二者内存、性能差异,介绍重写clone、JSON序列化、Apache工具类三种深拷贝实现方式,并说明Cloneable接口特性与两种拷贝适用场景。

目录

文章目录隐藏

  1. 1. 浅拷贝的原理
  2. 2. 深拷贝的原理
  3. 3. 浅拷贝和深拷贝的区别总结
  4. 知识拓展
  5. 总结

Java 中深拷贝与浅拷贝的区别是什么?

Java 开发中对象拷贝分为浅拷贝与深拷贝两类,二者内存复制逻辑差异极大,处理引用对象时容易出现数据污染问题。本文结合完整代码实例,分别讲解浅、深拷贝底层原理、实现方式与运行效果,梳理核心区别,同时拓展 Cloneable、JSON 序列化、工具类三种主流深拷贝实现方案,清晰区分两种拷贝的适用场景。

1. 浅拷贝的原理

1.1 什么是浅拷贝?

浅拷贝 是指在拷贝对象时,复制了对象的基础数据类型的字段值,但如果对象中包含引用类型的字段(如数组、集合、对象等),那么复制的是引用类型字段的引用,而不是引用对象本身。

  • 浅拷贝的特性
    • 基本数据类型会被复制一份。
    • 引用类型字段会复制引用,两个对象指向相同的内存地址。
    • 修改一个对象的引用类型字段,另一个对象也会受到影响。

1.2 浅拷贝的实现

代码示例:浅拷贝

class Person {
    String name;
    int age;
    Address address; // 引用类型字段

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

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

class Address {
    String city;

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

    @Override
    public String toString() {
        return city;
    }
}

public class ShallowCopyExample {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("John", 25, address);

        // 浅拷贝
        Person person2 = person1; // 这里是引用赋值,浅拷贝

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";

        // 输出结果
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}

输出结果:

person1: Person{name='John', age=25, address=Los Angeles}
person2: Person{name='John', age=25, address=Los Angeles}

解析

  • 由于 person2 = person1 是引用赋值,person1 和 person2 实际上指向的是同一个 Person 对象,且其 address 字段指向同一个 Address 对象。
  • 修改 person2 的 address.city,同时也改变了 person1 的 address.city,这是浅拷贝的典型问题。

2. 深拷贝的原理

2.1 什么是深拷贝?

深拷贝 是指拷贝对象时,不仅复制对象本身,而且递归地复制对象的所有引用类型字段。这样,原对象和新对象将拥有完全独立的内存空间,修改一个对象的引用类型字段,不会影响另一个对象。

  • 深拷贝的特性
    • 基本数据类型会被复制一份。
    • 引用类型字段会被完全复制,两个对象拥有独立的内存地址。
    • 修改一个对象的引用类型字段不会影响另一个对象。

2.2 深拷贝的实现

代码示例:深拷贝

class Person implements Cloneable {
    String name;
    int age;
    Address address;

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

    @Override
    public Person clone() throws CloneNotSupportedException {
        // 使用 Object 的 clone 方法进行浅拷贝
        Person cloned = (Person) super.clone();
        // 对引用类型进行深拷贝
        cloned.address = new Address(this.address.city);
        return cloned;
    }

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

class Address {
    String city;

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

    @Override
    public String toString() {
        return city;
    }
}

public class DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("New York");
        Person person1 = new Person("John", 25, address);

        // 深拷贝
        Person person2 = person1.clone(); // 调用克隆方法进行深拷贝

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";

        // 输出结果
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}

输出结果:

person1: Person{name='John', age=25, address=New York}
person2: Person{name='John', age=25, address=Los Angeles}

解析

  • 在深拷贝中,通过重写 clone() 方法,不仅拷贝了 Person 对象本身,还为 address 字段创建了新的 Address 对象。因此,person1 和 person2 完全独立。
  • 修改 person2 的 address.city 不会影响 person1,这就是深拷贝的好处。

3. 浅拷贝和深拷贝的区别总结

对比维度 浅拷贝(Shallow Copy) 深拷贝(Deep Copy)
对象复制 只复制对象本身,引用类型的字段共享内存地址 不仅复制对象本身,还递归复制所有引用类型字段
内存管理 新旧对象共享引用类型字段的内存地址 新旧对象的引用类型字段各自拥有独立内存
修改影响 修改一个对象的引用类型字段会影响另一个对象 修改一个对象的引用类型字段不会影响另一个对象
性能 性能较高,简单实现 性能较低,需递归复制所有对象及其字段
实现方式 可以通过赋值、clone() 等方式实现 通常需要自定义 clone() 或使用工具库

知识拓展

1. Java 的 Cloneable 接口与 clone() 方法

Java 中的 Cloneable 接口允许对象支持克隆功能。Object 类提供了一个默认的 clone() 方法,但该方法默认实现的是浅拷贝,若想实现深拷贝,通常需要重写 clone() 方法,并手动处理引用类型的字段。

  • Cloneable 接口是一个标记接口,表示对象可以被克隆。
  • 通过 super.clone() 实现对象的浅拷贝,再自行处理引用类型字段的深拷贝。

示例:Cloneable 的使用

class Address implements Cloneable {
    String city;

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

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

2. JSON 序列化与深拷贝

通过 JSON 序列化与反序列化 也可以轻松实现深拷贝。使用 Jackson 或 Gson 序列化对象后,再从 JSON 字符串恢复为新对象,从而实现深拷贝。

示例:使用 Jackson 实现深拷贝

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonDeepCopyExample {
    public static void main(String[] args) throws Exception {
        Person person1 = new Person("John", 25, new Address("New York"));
        
        ObjectMapper mapper = new ObjectMapper();
        // 序列化成 JSON 字符串
        String json = mapper.writeValueAsString(person1);

        // 从 JSON 字符串反序列化为新对象
        Person person2 = mapper.readValue(json, Person.class);

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";

        // 输出
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}

3. Apache Commons Lang 中的深拷贝

Apache Commons Lang 提供了一个工具类 SerializationUtils.clone(),可以通过序列化的方式实现对象的深拷贝。

示例:使用 Apache Commons Lang 进行深拷贝

import org.apache.commons.lang3.SerializationUtils;

public class ApacheCommonsDeepCopyExample {
    public static void main(String[] args) {
        Person person1 = new Person("John", 25, new Address("New York"));
        Person person2 = SerializationUtils.clone(person1); // 直接深拷贝

        person2.address.city = "Los Angeles";

        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
    }
}

总结

浅拷贝与深拷贝核心分界在于是否完整递归复制引用类型对象,浅拷贝性能高但数据互通,深拷贝数据完全隔离但开销更大。日常开发可根据对象结构选用对应实现方案,简单对象优先浅拷贝,多层嵌套引用对象则采用自定义克隆或序列化深拷贝,合理选择能规避数据互相篡改的线上隐患。

以上关于Java中深拷贝与浅拷贝的区别是什么?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

22

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Java中深拷贝与浅拷贝的区别是什么?