新闻详情

新闻详情

首页 / 资讯中心 / 详情

原型模式详解:克隆对象与浅克隆/深克隆

发布时间:2026/10/1 14:41:56来源:尧图网络
原型模式详解:克隆对象与浅克隆/深克隆
一、原型模式定义原型模式采用复制原型对象的方法来创建实例。使用原型模式创建出来的对象具有与原型一样的数据结构也拥有与原型一样的值。核心思想对象创建的动作发自原型对象自身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省去重复初始化用之前先想清楚——你的对象里有没有可变引用有就老老实实做深克隆否则改一个坑一片。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

基于SpringBoot的山西面食推广网站:毕业设计全流程开发指南 2026/10/1 17:02:01

基于SpringBoot的山西面食推广网站:毕业设计全流程开发指南

你如果正在为计算机毕业设计选题发愁,又恰好对餐饮、美食或者地方文化有点兴趣,那“基于SpringBoot的山西面食推广网站”这个题目,是真的值得认真考虑一下。市面上大部分毕设都在做商城、博客、管理系统,套路化严重,答…

阅读更多 →
DLSS5 in UE5尝鲜包解析:超分辨与帧生成实测指南 2026/10/1 17:01:54

DLSS5 in UE5尝鲜包解析:超分辨与帧生成实测指南

这几天好几个UE交流群里都在传一个带“仅供尝鲜”字样的包,名字直接写着“DLSS5 in UE5 2026.9.28”。说实话,第一眼看到这个日子和这个版本号,我心里就咯噔一下——这显然不是NVIDIA官方正式发布的版本号,更像是社区里某个玩家或…

阅读更多 →
CAN总线协议帧结构详解与硬件调试实战指南 2026/10/1 17:01:54

CAN总线协议帧结构详解与硬件调试实战指南

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

阅读更多 →
LeetCode 926:将字符串翻转到单调递增的完整解法与面试技巧 2026/10/1 17:01:53

LeetCode 926:将字符串翻转到单调递增的完整解法与面试技巧

第一次在算法题库里撞见“将字符串翻转到单调递增”这道题时,我的第一反应是——这题目看着简单,动起手来全是细节,而且区分度极高。LeetCode 第 926 题,给定一个只包含 0 和 1 的字符串,允许把任意位置的 0 翻成 1 或…

阅读更多 →
C# 上位机集成 OpenVINO + YOLOv8-OBB 旋转框检测实战 2026/10/1 17:01:53

C# 上位机集成 OpenVINO + YOLOv8-OBB 旋转框检测实战

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

阅读更多 →
T-Box深度解析:车联网核心硬件的市场格局与技术演进 2026/10/1 17:01:52

T-Box深度解析:车联网核心硬件的市场格局与技术演进

作为在车联网行业摸爬滚打了十来年的从业者,这两年被问得最多的一个词就是“T-Box”。不管是做前装量产的朋友,还是后装市场的玩家,甚至搞投资的朋友,见面聊不了几句就会绕到T-Box上。这玩意儿确实是智能汽车时代绕不开的核心硬件…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉