深克隆和浅克隆(建造者模式,内含简版)

让我们来看一个例子:

设计一个客户类Customer,其中客户地址存储在地址类Address中,用浅克隆和深克隆分别实现Customer对象的复制并比较这两种克隆方式的异同。

代码实现

Customer类和Address类都是实现的Java 内置的 java.lang.Cloneable 接口,无需自己定义

1. ​Customer 类

package experiment05.二;public class Customer implements Cloneable {private String name;private int age;private Address address;// 构造方法接受 CustomerBuilder 参数public Customer(CustomerBuilder builder) {this.name = builder.getName();this.age = builder.getAge();this.address = builder.getAddress();}// 浅克隆@Overridepublic Customer clone() throws CloneNotSupportedException {return (Customer) super.clone();}// 深克隆public Customer deepClone() throws CloneNotSupportedException {Customer cloned = (Customer) super.clone();cloned.address = this.address.clone();return cloned;}// Getter 方法public Address getAddress() {return address;}public String getName() {return name;}public int getAge() {return age;}
}

2. ​CustomerBuilder 类

package experiment05.二;public class CustomerBuilder {private String name;private int age;private Address address;public CustomerBuilder withName(String name) {this.name = name;return this;}public CustomerBuilder withAge(int age) {this.age = age;return this;}public CustomerBuilder withAddress(Address address) {this.address = address;return this;}public Customer build() {return new Customer(this);}// 提供给 Customer 构造方法访问的 GetterString getName() {return name;}int getAge() {return age;}Address getAddress() {return address;}
}

3.Address 类

package experiment05.二;public class Address implements Cloneable {private String street;private String city;public Address(String street, String city) {this.street = street;this.city = city;}@Overridepublic Address clone() throws CloneNotSupportedException {return (Address) super.clone();}public void setStreet(String street) {this.street = street;}public String getStreet() {return street;}public String getCity() {return city;}
}

4. ​Main 类

package experiment05.二;public class Main {public static void main(String[] args) throws CloneNotSupportedException {// 使用独立建造者类创建对象(链式写法)Customer original = new CustomerBuilder().withName("张三").withAge(30).withAddress(new Address("人民路123号", "北京市"))//以上三个的编译类型和运行类型都是CustomerBuilder.build();// 只有这个返回的是Customer对象(Customer的编译运行类型),build()方法实际返回的是new Customer(...)对象/*** 编译类型由变量声明或方法返回类型决定* 运行类型由实际创建的对象决定*//*     ==等效于==步骤1:创建建造者对象CustomerBuilder builder1 = new CustomerBuilder(); // ✅ 编译类型=运行类型=CustomerBuilder步骤2:设置姓名(返回建造者)CustomerBuilder builder2 = builder1.withName("张三"); // ✅ 编译类型=运行类型=CustomerBuilder步骤3:设置年龄(返回建造者)CustomerBuilder builder3 = builder2.withAge(30); // ✅ 编译类型=运行类型=CustomerBuilder步骤4:设置地址(返回建造者)CustomerBuilder builder4 = builder3.withAddress(new Address("人民路123号", "北京市")); // ✅ 类型同上步骤5:构建最终对象Customer original = builder4.build(); // ✅ 编译类型=Customer | 运行类型=Customer*/// 浅克隆和深克隆Customer shallowCopy = original.clone();Customer deepCopy = original.deepClone();// 修改原对象地址original.getAddress().setStreet("长安街456号");// 验证结果System.out.println("原始对象地址: " + original.getAddress().getStreet());      // 长安街456号System.out.println("浅克隆对象地址: " + shallowCopy.getAddress().getStreet()); // 长安街456号System.out.println("深克隆对象地址: " + deepCopy.getAddress().getStreet());    // 人民路123号}
}

简单版 (无建造者)

class Address implements Cloneable {private String street;private String city;public Address(String street, String city) {this.street = street;this.city = city;}@Overridepublic Address clone() throws CloneNotSupportedException {return (Address) super.clone();}public void setStreet(String street) {this.street = street;}public String getStreet() {return street;}
}class Customer implements Cloneable {private String name;private int age;private Address address;// 直接使用构造方法初始化public Customer(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}// 浅克隆@Overridepublic Customer clone() throws CloneNotSupportedException {return (Customer) super.clone();}// 深克隆public Customer deepClone() throws CloneNotSupportedException {Customer cloned = (Customer) super.clone();cloned.address = this.address.clone();return cloned;}public Address getAddress() {return address;}public String getName() {return name;}
}public class Main {public static void main(String[] args) throws CloneNotSupportedException {// 直接使用构造方法创建对象Customer original = new Customer("张三", 30, new Address("人民路123号", "北京市"));Customer shallowCopy = original.clone();Customer deepCopy = original.deepClone();original.getAddress().setStreet("长安街456号");System.out.println("原始对象地址: " + original.getAddress().getStreet());     // 长安街456号System.out.println("浅克隆对象地址: " + shallowCopy.getAddress().getStreet()); // 长安街456号System.out.println("深克隆对象地址: " + deepCopy.getAddress().getStreet());    // 人民路123号}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42075.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Windows 上安装并使用 Postman?

Postman 是一个功能强大的API测试工具,它可以帮助程序员更轻松地测试和调试 API。在本文中,我们将讨论如何在 Windows 上安装和使用 Postman。 Windows 如何安装和使用 Postman 教程?

便携版:随时随地,高效处理 PDF 文件

PDF-XChange Editor Plus 便携版是一款功能强大且极其实用的 PDF 阅读与编辑工具。它不仅支持快速浏览 PDF 文件,还提供了丰富的编辑功能,让用户可以轻松处理 PDF 文档。经过大神优化处理,这款软件已经变得十分轻便,非常适合需要随…

MCP Server 实现一个 天气查询

​ Step1. 环境配置 安装 uv curl -LsSf https://astral.sh/uv/install.sh | shQuestion: 什么是 uv 呢和 conda 比有什么区别? Answer: 一个用 Rust 编写的超快速 (100x) Python 包管理器和环境管理工具,由 Astral 开发。定位为 pip 和 venv 的替代品…

MySQL执行计划

MySQL 的 执行计划(Execution Plan) 是优化器根据 SQL 语句生成的查询执行路径的详细说明。通过分析执行计划,可以了解 MySQL 如何处理 SQL 查询(如索引使用情况、表连接顺序等),进而优化查询性能。 1. 获…

数据大屏点亮工业互联网的智慧之眼

在当今数字化飞速发展的时代,数据已成为企业决策的核心依据,而数据大屏作为数据可视化的重要工具,正逐渐成为工业互联网领域不可或缺的一部分。通过直观、动态的可视化展示,数据大屏能够将复杂的数据转化为易于理解的图表和图形&a…

GPT-SoVITS本地部署:低成本实现语音克隆远程生成音频全流程实战

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 今天要给大家安利一个绝对能让你大呼过瘾的声音黑科技——GPT-SoVITS!这款由花儿不哭大佬精心打造的语音克隆神…

【AI大模型】DeepSeek + 通义万相高效制作AI视频实战详解

目录 一、前言 二、AI视频概述 2.1 什么是AI视频 2.2 AI视频核心特点 2.3 AI视频应用场景 三、通义万相介绍 3.1 通义万相概述 3.1.1 什么是通义万相 3.2 通义万相核心特点 3.3 通义万相技术特点 3.4 通义万相应用场景 四、DeepSeek 通义万相制作AI视频流程 4.1 D…

【Unity】合批处理和GPU实例化的底层优化原理(完)

【Unity】批处理和实例化的底层优化原理 URP1.基础概念SetPassCallsDrawCallsBatches 2.重要性排序既然如此为什么仍然要合批? 3.unity主流的合批优化方案和优先级Early-Z透明物体情况 4.合批(小场景但是很复杂很多小物件刚需)合并纹理图集更…

当人类关系重构:从“相互需要”到“鹅卵石化”——生成式人工智能(GAI)认证的角色与影响

在数字化浪潮的席卷之下,人类社会正经历着前所未有的变革。人与人之间的连接方式、互动模式以及价值认同,都在悄然发生着变化。这一过程中,一个显著的现象是,人与人之间的关系逐渐从传统的“相互需要”模式,转变为一种更为复杂、多元且稳定的“鹅卵石化”结构。在此背景下…

ctfhow——web入门171~175

sql简介 web入门171 ——判断注入点: -1 union select 1,2,3 -- 其实在这之前可以先判断多少列,即 -1‘ group(order) by 3 -- group by用于将具有相同值的行分组成一个汇总行,可以查看是否报错确定列数 2&#x…

vue遗漏的知识点(动态组件.组件库的操作使用)

----动态组件&#xff08;vue2vue3通用&#xff09; <component :is"..."> 的作用 <component> 是 Vue 的内置组件&#xff0c;用于动态渲染其他组件。:is 属性 用于指定要渲染的组件。它的值可以是&#xff1a; 组件的名称&#xff08;字符串&#xf…

ip改变导致的数据库连接不上

前言 需要用到路由器&#xff0c;所以先把家里的路由器给拆了先用着。新的路由器到了之后&#xff0c;更换上新的路由器之后&#xff0c;调用到服务会有报错&#xff0c;记录一下更换路由器之后ip重新分配服务可能会报的错. 进一步可以看到有关网路在服务当中的影响。 正文 …

DeepSeek面试——模型架构和主要创新点

本文将介绍DeepSeek的模型架构多头潜在注意力&#xff08;MLA&#xff09;技术&#xff0c;混合专家&#xff08;MoE&#xff09;架构&#xff0c; 无辅助损失负载均衡技术&#xff0c;多Token 预测&#xff08;MTP&#xff09;策略。 一、模型架构 DeepSeek-R1的基本架构沿用…

基于HTML5的3D魔方项目开发实践

基于HTML5的3D魔方项目开发实践 这里写目录标题 基于HTML5的3D魔方项目开发实践项目概述核心技术实现1. 3D效果实现CSS3 3D变换魔方结构设计 2. 交互控制实现动画控制键盘控制触摸控制 技术难点与解决方案1. 3D变换控制2. 触摸体验优化3. 动画性能优化 项目收获总结项目展望 项…

23种设计模式-原型(Prototype)设计模式

原型设计模式 &#x1f6a9;什么是原型设计模式&#xff1f;&#x1f6a9;原型设计模式的特点&#x1f6a9;原型设计模式的结构&#x1f6a9;原型设计模式的优缺点&#x1f6a9;原型设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是原型设计模式…

【MATLAB例程】交互式多模型(IMM),模型使用:CV,CT左转、CT右转,二维平面,三个模型的IMM,滤波使用EKF。订阅专栏后可查看代码

简单的介绍:本文所述的代码实现了一种基于交互多模型(IMM)算法的目标跟踪仿真,适用于复杂运动目标(如匀速、转弯运动)的状态估计。代码通过三个运动模型(匀速CV、左转弯CT1、右转弯CT2)的协同滤波,动态调整模型概率,最终输出综合跟踪结果。代码包含完整的仿真数据生成…

搭建私人对外git空间

# 创建用户&#xff0c;指定不可登录的 Shell&#xff08;git-shell 或 /usr/sbin/nologin&#xff09; sudo adduser --system --shell /usr/bin/git-shell --group git # 验证用户配置 grep git /etc/passwd # 预期输出&#xff1a;git:x:998:998::/home/git:/usr/bin/git-s…

PHP中yield关键字的使用

PHP版本>5.5 原理&#xff1a;yield关键字会生成一个Generator类的对象&#xff0c;PHP通过Generator实例计算出下一次迭代的值&#xff0c;再次返回一个Generator对象并停止循环&#xff08;即循环一次执行一次&#xff09;。 理解&#xff1a;使用在for/foreach/while循…

Vue3 实战:基于 mxGraph 与 WebSocket 的动态流程图构建

本文将详细介绍如何在 Vue3 项目中集成 mxGraph 可视化库&#xff0c;并通过 WebSocket 实现画布元素的实时更新。适合有 Vue 基础的前端开发者学习参考。 一、技术栈准备 Vue3&#xff1a;采用 Composition API 开发mxGraph&#xff1a;JavaScript 流程图库&#xff08;版本 …

Linux目录及文件管理

目录 一.Linux目录基本结构 1.常见目录及其作用 二.常用文件处理命令 1.七类常见的linux的文件 2.cat&#xff08;查看文件内容&#xff09; 3.more(分页查看文件内容&#xff09; 4.less(分页查看文件内容&#xff09; 5.head&#xff08;从头部查看文件内容&#xff0…