原型模式详解:克隆对象与浅克隆/深克隆
一、原型模式定义原型模式采用复制原型对象的方法来创建实例。使用原型模式创建出来的对象具有与原型一样的数据结构也拥有与原型一样的值。核心思想对象创建的动作发自原型对象自身clone()而不是由外部new出来。二、原型模式的特点由原型对象自身创建目标对象即对象创建这一动作来自原型对象本身的clone()方法。目标对象是原型的一个克隆通过原型模式创建的对象不仅与原型有相同的结构还有相同的值。根据克隆深度的不同分浅度克隆与深度克隆见第四节。三、基础代码实现Object类自带protected Object clone()但只有实现了Cloneable标记接口的类调用clone()才不会抛CloneNotSupportedException。// 必须实现 Cloneable 接口才能克隆publicclassPersonimplementsCloneable{privateStringname;privateStringage;privateStringsex;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicStringgetAge(){returnage;}publicvoidsetAge(Stringage){this.ageage;}publicStringgetSex(){returnsex;}publicvoidsetSex(Stringsex){this.sexsex;}// 克隆方法重写 Object.clone()提升为 publicOverridepublicPersonclone(){try{return(Person)super.clone();// 默认是【浅克隆】}catch(CloneNotSupportedExceptione){e.printStackTrace();returnnull;}}}publicclassMainClass{publicstaticvoidmain(String[]args){Personperson1newPerson();person1.setName(李白);person1.setAge(34);person1.setSex(男);// 克隆对象堆里生成了一份新对象Personperson2person1.clone();System.out.println(person2.getName());// 李白与原型数据一致}}⚠️super.clone()默认执行的是浅克隆见下节。这里的字段都是String不可变和基本类型浅克隆看不出副作用。四、浅克隆 vs 深克隆核心4.1 一个关键澄清super.clone()的本质是逐字段复制。基本类型int、double…直接复制值互不干扰引用类型对象、数组…只复制引用地址新旧对象指向同一个引用对象。原笔记说数值对象会生成全新一份并不准确——String是引用类型只是因为它不可变即使浅克隆共享了引用重新赋值p.namex也只是让p指向新字符串不会改动原对象所以看起来没副作用。要真正暴露浅克隆问题必须用可变引用对象。4.2 浅克隆的副作用用可变对象演示给Person增加一个可变的引用属性AddresspublicclassAddressimplementsCloneable{privateStringcity;publicAddress(Stringcity){this.citycity;}publicStringgetCity(){returncity;}publicvoidsetCity(Stringcity){this.citycity;}OverridepublicAddressclone(){try{return(Address)super.clone();}catch(CloneNotSupportedExceptione){returnnull;}}}publicclassPersonimplementsCloneable{privateStringname;privateAddressaddress;// 可变引用对象// 浅克隆address 引用被复制p1、p2 指向同一个 AddressOverridepublicPersonclone(){try{return(Person)super.clone();}catch(CloneNotSupportedExceptione){returnnull;}}}publicclassMainClass{publicstaticvoidmain(String[]args){Personp1newPerson(李白,newAddress(长安));Personp2p1.clone();// 浅克隆p2.getAddress().setCity(洛阳);// 改 p2 的地址System.out.println(p1.getAddress().getCity());// 输出洛阳p1 被牵连}}结论浅克隆下p1和p2共享同一个Address改一个另一个跟着变——这通常不是我们想要的。4.3 深克隆的修法深克隆 在clone()里连引用对象也一起克隆publicclassPersonimplementsCloneable{privateStringname;privateAddressaddress;OverridepublicPersonclone(){try{Personp(Person)super.clone();p.addressthis.address.clone();// 引用对象也克隆一份returnp;}catch(CloneNotSupportedExceptione){returnnull;}}}此时p2.getAddress().setCity(洛阳)不会影响p1二者完全独立。4.4 深克隆的另一种方式序列化当对象层级很深时逐层clone()很繁琐。可让类实现Serializable通过序列化成字节流再反序列化得到完全独立的新对象要求所有引用对象都可序列化// 伪代码思路把对象写进 ByteArrayOutputStream再读回 → 全新深拷贝面试常问深克隆两种实现——逐层 clone()或序列化。前者直观但层次深时繁琐后者一行深拷贝但要求全链路可序列化。五、角色与职责角色职责抽象原型Prototype声明克隆自身的接口。Java 中即Cloneable标记接口 clone()方法具体原型Concrete Prototype实现clone()返回自身的一个副本客户Client通过调用原型的clone()创建新对象而不使用new六、应用场景创建对象时希望新对象既继承基类结构又继承原型的数据直接clone比从头new再逐个set更高效。希望修改目标对象不影响既有原型配合深克隆克隆体与原型完全隔离。隐藏克隆细节对象本身的克隆往往涉及类内部数据细节用原型模式把这些细节封装在clone()内调用方无感知。对象创建成本高 / 构造复杂如从数据库或网络加载后缓存为原型后续直接复制省去昂贵初始化。七、总结原型模式 复制现有对象来创建新对象而非new。浅克隆复制基本类型值 复制引用地址引用对象共享深克隆引用对象也一并克隆完全独立。String不可变单用String字段无法体现浅克隆问题必须用可变引用对象演示。记忆浅克隆共享引用、深克隆独立副本层次深时用序列化做深克隆更省事。一句话总结原型模式用clone()拷贝代替new省去重复初始化用之前先想清楚——你的对象里有没有可变引用有就老老实实做深克隆否则改一个坑一片。

相关新闻

Cursor AI编程实战:把Base URL改到TaoToken,统一Key接入多模型

Cursor AI编程实战:把Base URL改到TaoToken,统一Key接入多模型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 14:41:56 阅读更多 →
Ubuntu Vulkan环境搭建:四层信任链验证与llamacpp GPU推理实战

Ubuntu Vulkan环境搭建:四层信任链验证与llamacpp GPU推理实战

1. 项目概述:为什么在Ubuntu上装Vulkan不是“装个驱动”那么简单Vulkan不是某个软件,而是一套跨平台、低开销、显式控制的图形与计算API规范。它不像OpenGL那样自带大量状态机和隐式行为,而是把显卡调度、内存管理、同步机制这些原本由驱动代…

2026/10/1 14:41:56 阅读更多 →
PMSM Foc控制杂谈二:打通“角度闭环,电压开环”的任督二脉

PMSM Foc控制杂谈二:打通“角度闭环,电压开环”的任督二脉

当我们成功通过 SPI 读取到磁编码器的数值,并在代码中手动给出一个 $V_q 0.5V$ 的指令,看着电机丝滑地旋转起来时,这意味着我们已经跨越了无刷电机控制最陡峭的一段学习曲线。在这个阶段,系统处于一个非常有趣且关键的中间态&…

2026/10/1 14:41:56 阅读更多 →

最新新闻

2026年北京小程序/App开发公司选型指南:从技术架构到服务能力全维度解析

2026年北京小程序/App开发公司选型指南:从技术架构到服务能力全维度解析

一、为什么2026年选对开发服务商比以往更关键过去两年,小程序和App开发市场经历了一轮明显的分化。一方面,企业对数字化产品的需求从“有没有”转向“好不好用”;另一方面,AI能力集成、多端适配、高并发架构等要求让开发项目的技术…

2026/10/1 15:31:19 阅读更多 →
国密 UKey 证书到期自动续期怎么落地:安当UKey 的双证书过渡实践

国密 UKey 证书到期自动续期怎么落地:安当UKey 的双证书过渡实践

国密 UKey 证书到期自动续期怎么落地:安当UKey 的双证书过渡实践 在很多政企与金融客户的信创改造项目里,国密 UKey 已经成了身份鉴别与会话加密的"硬底座"。它把 SM2 私钥锁在国密安全芯片里,私钥不可导出,天然解决了软…

2026/10/1 15:31:19 阅读更多 →
神经网络参数初始化全解析:从梯度传播原理到PyTorch实战

神经网络参数初始化全解析:从梯度传播原理到PyTorch实战

训练神经网络这几年,我有一多半的“模型不收敛”最终都指向同一个元凶——不是网络搭错了,不是学习率没调好,也不是数据喂得不对,而是参数初始化没做好。很多人把PyTorch当黑盒,模型构建完直接传数据、算loss、backwar…

2026/10/1 15:31:19 阅读更多 →
强化学习中的HER:用事后经验回放破解稀疏奖励难题

强化学习中的HER:用事后经验回放破解稀疏奖励难题

先聊一个很微妙的心理现象:事情明明搞砸了,过一会儿回过头看,你总觉得“我早就知道会这样”。心理学管这叫hindsight bias(后见之明偏差),放在日常里就是事后诸葛亮。但在我接触过的强化学习项目里&#xf…

2026/10/1 15:31:19 阅读更多 →
HarmonyOS 7 + ArkTS/Hvigor:上架审核前的隐私声明一致性扫描【鸿蒙心迹】

HarmonyOS 7 + ArkTS/Hvigor:上架审核前的隐私声明一致性扫描【鸿蒙心迹】

审核被打回时,真正费时间的往往不是改一行配置,而是确认代码、权限、SDK、隐私政策和后台声明到底哪一处没有对齐。一、审核意见只有一句,排查却横跨四个地方 这次遇到的审核意见并不复杂:“应用实际申请的权限与隐私政策说明不一…

2026/10/1 15:31:19 阅读更多 →
Windows 下 CLion 与 ESP-IDF 环境配置实战:从安装到调试的完整指南

Windows 下 CLion 与 ESP-IDF 环境配置实战:从安装到调试的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 15:30:19 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →