Java设计模式-原型模式
1、定义
原型模式是一种创建型模式,用于创建重复的对象,并且保证性能。原型模式创建的对象是由原型对象自身创建的,是原型对象的一个克隆,和原型对象具有相同的结构和相同的值。
2、适用场景
- 创建对象时我们不仅仅需要创建一个新的对象,可能我们还需要对象创建出来里面的值和某一个对象也要完全一致,原型模式可以保证结构和值都相同。
- 创建对象时我们希望对创建出来的对象的修改不影响到原来的对象,可能通过原型模式进行创建,进行深度克隆。
- 创建对象时,如果对象是个复杂对象,里面又包含了其他的复杂对象,我们希望创建的对象和原有对象保持一致,传统模式new会非常麻烦,还需要考虑到里面其他的复杂对象,这时候可以使用原型模式进行创建。
3、 原型模式的核心是就是原型类 Prototype,Prototype 类需要具备以下两个条件:
- (1)实现 Cloneable 接口:在 Java 中 Cloneable 接口的作用就是在运行时通知虚拟机可以安全地在实现了 Cloneable 接口的类上使用 clone() 方法,只有在实现了 Cloneable 的类才可以被拷贝,否则在运行时会抛出 CloneNotSupportedException 异常。
- (2)重写 Object 类中的 clone() 方法:Java 中所有类的父类都是 Object,Object 中有一个clone() 方法用于返回对象的拷贝,但是其作用域 protected,一般的类无法调用,因此,Prototype 类需要将 clone() 方法的作用域修改为 public。
原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。
4、注意事项
(1)使用原型模式复制对象不会调用类的构造函数,对象是通过调用 Object 类的 clone() 方法来完成的,它直接在内存中复制数据。不但构造函数不会执行,甚至连访问权限都对原型模式无效。单例模式中,需要将构造函数的访问权限设置为 private,但是 clone() 方法直接无视构造方法的权限,所以单例模式与原型模式是冲突的,在使用时需要注意。
(2)深拷贝与浅拷贝。Object 类的 clone() 方法只会拷贝对象中的基本的数据类型(8种基本数据类型 byte,char,short,int,long,float,double,boolean 和对应的封装类),对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。
- 浅拷贝:只克隆对象中的基本数据类型,而不会克隆数组、容器、引用对象等。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。如果变量为String字符串,则拷贝其引用地址,但是在修改的时候,它会从字符串池中重新生成一个新的字符串,原有的字符串对象保持不变。
- 深拷贝:把要克隆的对象所引用的对象都克隆了一遍。
代码实例
/*** @Author charles.yao* @Description* @Date 2023/2/13 14:54*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Animal implements Cloneable {private String userName;private String userAge;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}/*** @Author charles.yao* @Description 浅拷贝类* @Date 2023/2/13 14:53*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserInfo implements Cloneable {private String userName;private String userAge;private Animal animal;@Overrideprotected UserInfo clone() throws CloneNotSupportedException {UserInfo userInfo = (UserInfo) super.clone();userInfo.setAnimal((Animal) animal.clone());return userInfo;}
}/*** @Author charles.yao* @Description 浅拷贝测试* @Date 2023/2/13 14:57*/
public class DeepCopyTest {public static void main(String[] args) {try {UserInfo userInfo = new UserInfo();userInfo.setUserName("张三");userInfo.setUserAge("1223");userInfo.setAnimal(new Animal("111", "2122"));UserInfo clone = userInfo.clone();System.out.println("原数据" + userInfo.toString());System.out.println("拷贝之后" + clone.toString());System.out.println(userInfo == clone);System.out.println(userInfo.getAnimal() == clone.getAnimal());userInfo.getAnimal().setUserName("二狗");System.out.println("原数据动物" + userInfo.getAnimal().toString());System.out.println("拷贝之后动物" + clone.getAnimal().toString());} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}
运行结果
原数据UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
拷贝之后UserInfo(userName=张三, userAge=1223, animal=Animal(userName=111, userAge=2122))
false
false
原数据动物Animal(userName=二狗, userAge=2122)
拷贝之后动物Animal(userName=111, userAge=2122)
相关文章:
Java设计模式-原型模式
1、定义 原型模式是一种创建型模式,用于创建重复的对象,并且保证性能。原型模式创建的对象是由原型对象自身创建的,是原型对象的一个克隆,和原型对象具有相同的结构和相同的值。 2、适用场景 创建对象时我们不仅仅需要创建一个新…...

2023年度最新且最详细Ubuntu的安装教程
目录 准备ISO镜像 1.去官网下载镜像,或者找有镜像源的网站下载 阿里云镜像站 2. 如果服务器是打算直接把底层系统安装为Ubuntu的话还需制作系统U盘 安装 1.新建虚拟机调整基础配置 2.打开电源,进入安装界面(到这一步就跟u盘安装步骤一致…...

unix高级编程-fork之后父子进程共享文件
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. 这里我看到的是centos的操作,但我用的是debian系的ubuntu,百度了一下发现debian的在这里…...

vue+echarts:柱状图横向展示和竖向展示
第021个点击查看专栏目录本示例是显示柱状图,分别是横向展示和纵向展示。关键是X轴和Y轴的参数互换。 文章目录横向示例效果横向示例源代码(共81行)纵向示例效果纵向示例源代码(共81行)相关资料参考专栏介绍横向示例效…...

SealOS 一键安装 K8S
环境 # 查看系统发行版 $ cat /etc/os-release NAME"CentOS Linux" VERSION"7 (Core)" ID"centos" ID_LIKE"rhel fedora" VERSION_ID"7" PRETTY_NAME"CentOS Linux 7 (Core)" ANSI_COLOR"0;31" CPE_NA…...

python网络编程详解
最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容,结合自己后台开发的经验,写下这篇文章,一方面是为了帮助有需要的人,更重要的是方便自己整理思路,加…...

ICRA 2023 | 首个联合暗光增强和深度估计的自监督方法STEPS
原文链接:https://www.techbeat.net/article-info?id4629 作者:郑宇鹏 本文中,我们提出了STEPS,第一个自监督框架来联合学习图像增强和夜间深度估计的方法。它可以同时训练图像增强网络和深度估计网络,并利用了图像增…...

基于react+nodejs+mysql开发用户中心,用于项管理加入的项目的用户认证
基于reactnodejsmysql开发用户中心,用于项管理加入的项目的用户认证用户中心功能介绍页面截图后端采用架构user表projects表project_user表仓库地址用户中心功能介绍 用户中心项目,用于统一管理用户信息、登录、注册、鉴权等 功能如下: 用…...

mapreduce与yarn
文章目录一、MapReduce1.1、MapReduce思想1.2、MapReduce实例进程1.3、MapReduce阶段组成1.4、MapReduce数据类型1.5、MapReduce关键类1.6、MapReduce执行流程1.6.1、Map阶段执行流程1.6.2、Map的shuffle阶段执行流程1.6.3、Reduce阶段执行流程1.7、MapReduce实例WordCount二、…...
鲲鹏云服务器上使用 traceroute 命令跟踪路由
traceroute 命令跟踪路由 它由遍布全球的几万局域网和数百万台计算机组成,并通过用于异构网络的TCP/IP协议进行网间通信。互联网中,信息的传送是通过网中许多段的传输介质和设备(路由器,交换机,服务器,网关…...
代码随想录算法训练营第47天 || 198.打家劫舍 || 213.打家劫舍II || 337.打家劫舍III
代码随想录算法训练营第47天 || 198.打家劫舍 || 213.打家劫舍II || 337.打家劫舍III 198.打家劫舍 题目介绍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&…...

JVM调优方式
对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数。 1.Full GC 会对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比较慢,因此应该尽可能减少Full GC的次数。 2.导致Full GC的原因 1)年老…...
机器学习模型监控的 9 个技巧
机器学习 (ML) 模型是非常敏感的软件;它们的成功使用需要进行仔细监控以确保它们可以正常工作。当使用所述模型的输出自动做出业务决策时尤其如此。这意味着有缺陷的模型通常会对终端客户的体验产生真正的影响。因此,监控输入数据(和输出&…...

Linux 实现鼠标侧边键实现代码与网页的前进、后退
前言 之前一直是使用windows进行开发,最近转到linux后使用VsCode编写代码。 但是不像在win环境下,使用鼠标侧边键可以实现代码的前向、后向跳转。浏览网页时也不行(使用Alt Left可以后退)。 修改键盘映射实在没有那么方便&…...

健身蓝牙耳机推荐,推荐五款适合健身的蓝牙耳机
出门运动健身,有音乐的陪伴是我们坚持运动的不懈动力,在健身当中佩戴的耳机,佩戴舒适度以及牢固程度是我们十分需要注意的,还不知道如何选择健身蓝牙耳机,可以看看下面这些运动蓝牙耳机分享。 1、南卡Runner Pro4骨传…...

Type-c诱骗取电芯片大全
随着Type-C的普及和推广,目前市面上的电子设备正在慢慢淘汰micro-USB接口,逐渐都更新成了Type-C接口,micro-USB接口从2007年上市,已经陪伴我们走过十多个年头,如今也慢慢退出舞台。 今天我们评测的产品是市面上Type-C…...

Scala模式匹配详解(第八章:基本语法、模式守卫、模式匹配类型)(尚硅谷笔记)
模式匹配第 8 章 模式匹配8.1 基本语法8.2 模式守卫8.3 模式匹配类型8.3.1 匹配常量8.3.2 匹配类型8.3.3 匹配数组8.3.4 匹配列表8.3.5 匹配元组8.3.6 匹配对象及样例类8.4 变量声明中的模式匹配8.5 for 表达式中的模式匹配8.6 偏函数中的模式匹配(了解)第 8 章 模式匹配 Scal…...

Linux:基于libevent读写管道代码
基于libevent读写管道代码: 读端: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <event2/event.h> #include…...
2022年中职网络安全逆向题目整理合集
中职网络安全逆向题目整理合集逆向分析:PE01.exe算法破解:flag0072算法破解:flag0073算法破解:CrackMe.exe远程代码执行渗透测试天津逆向re1 re2逆向分析:PE01.exe FTPServer20220509(关闭链接) FTP用户名:PE01密码…...

Tencent OS下逻辑卷(LVM)增加硬盘扩容
上一篇文章写了逻辑卷创建以及使用剩余空间为已经创建的逻辑卷扩容。 本篇是针对卷组空间已经用尽时的扩容方法。那就是增加硬盘。 首先我们为虚拟机增加硬盘/dev/sdd 使用fdisk为/dev/sdd分区,方法在上一篇文章已经描述,在此不再赘述。 新增的硬盘使用如下命令添加到卷组…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...