站稳马步——(2)clone(克隆)、Cloneable

达梦数据库(DM)的备份与恢复功能 本文系统介绍了达梦数据库(DM)的备份与恢复功能,主要包括作业系统和物理/逻辑备份还原两大模块。作业系统部分详细说明了通过代理环境创建定时备份和删除备份作业的步骤;物理备份还原部分阐述了联机和脱机备份方式,包括数据库、表空间、表和归档的备份还原操作;逻辑备份还原部分介绍了dexp/dimp工具的使用方法及四种级别的导入导出功能。文章还介绍了图形化管理工具进行备份还原的操作流程,全面覆盖了达梦数据库的数据保护方案,为数据库管理员提供了详细的技术指导。 阅读详情

站稳马步

——整理 Object 类—— clone (克隆)

 

A.  关键字:

Object 、 clone ()、 Cloneable 接口、克隆、浅拷贝、深拷贝

 

B.  为什么需要克隆?

如果你碰到这种情况,你感觉是否需要 copy 一份呢?

假设你从数据库中得到一个 List<T> 列表后,你需要在各种情况下对此列表进行重新包装后返回此列表,那怎么办呢?如果在各种不同情况下分别去数据库取这个 List ,来操作,那岂不是要多次操作数据库!?于是,我一次读出,然后在不同情况下,对它进行 copy 。

 

 

C.  错误的实现:

         People p1= new People () ;

       People p2= new People () ;

       p 2=p1;

       // 或

       People p 3=p1;

         或许,好多新手都会认为 p2 、 p3 都是 p1 的拷贝。 P2 虽然申请了内存空间,但转而又指向 p1 的内存引用( 刚才 new 的操作等于制造一堆垃圾等着 JVM 回收 ); p3 和 p1 只不过是 2 个不同的变量指向同一内存区域。可以说: p1 、 p2 、 p3 依然是同一对象。

    

   

D.  正确实现:

1.       看看 Object 的源代码:

protectednative Object clone () throws CloneNotSupportedException;

可见是受保护的( protected ),而且是调用本地方法( native )

Clone() 规范约定如下:

(1)clone() 将对象复制了一份并返回给调用者。一般而言,clone ()方法满足:

① 对任何的对象x ,都有x.clone() !=x// 克隆对象与原对象不是同一个对象

② 对任何的对象x ,都有x.clone().getClass()= =x.getClass()// 克隆对象与原对象的类型一样

③ 如果对象x 的equals() 方法定义恰当,那么x.clone().equals(x) 应该成立。

 

(2)Java 中对象的克隆

① 为了获取对象的一份拷贝,我们可以利用Object 类的clone() 方法。

② 在派生类中覆盖基类的clone() 方法,并声明为public 。

③ 在派生类的clone() 方法中,调用super.clone() 。

④ 在派生类中实现Cloneable 接口。

 

 

2.       Demo:

   测试类:

import java.util.ArrayList;

import java.util.List;

/**

  * @description :

  * 简单类克隆实现 <br>

  * 要实现克隆 , 必须实现 Cloneable 接口 , 这是一个标识接口 , 没有接口方法 <br>

  * 实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。 <br>

  * 按照惯例,实现此接口的类应该使用公共方法重写 Object.clone (它是受保护的)。

  *

  * @author Ydj

  * @createTime Oct 31, 2010 2:27:46 PM

  * @version   1.0

  */

public class TestClone {

    /**

      * @param args

      */

    public static void main ( String [] args ) {

       // TODO Auto-generated method stub

       People a= new People (( byte ) 1, "ydj" ,26 ) ;

      

       Room room= new Room ( " 别墅 A" ) ;

       a. setRoom ( room ) ;

      

       List < Car > cars= new ArrayList < Car > () ;

       cars.add ( new Car ( " 越野 " , "Jeep1" )) ;

       cars.add ( new Car ( " 商务 " , "Hongqi" )) ;

       a. setCars ( cars ) ;

 

       People p1= new People () ;

       People p2= new People () ;

       p2=p1; // 或 People p3=p1;// 都是错误的复制

      

       People b = ( People ) a. clone () ;

      

       System .out . println (( a==b )) ;

       System .out . println ( " 原本 姓名: " +a. getName () + " 年龄: " +a. getAge () + " 房子名字: " +a. getRoom () . getName () + " 拥有车子数: " +a. getCars () .size ()) ;

       System .out . println ( " 副本 姓名: " +b . getName () + " 年龄: " +b . getAge () + " 房子名字: " +b . getRoom () . getName () + " 拥有车子数: " +b . getCars () .size ()) ;

      

       b . setName ( "yidej" ) ;

       b . setAge ( 25 ) ;

       b . getRoom () . setName ( " 别墅 B" ) ;

       b . getCars () .add ( new Car ( " 复制后加一部车 " , "XXX" )) ;

      

      

       System .out . println ( "############## 修改副本的一些属性后 ##############" ) ;

       System .out . println ( " 原本 姓名: " +a. getName () + " 年龄: " +a. getAge () + " 房子名字: " +a. getRoom () . getName () + " 拥有车子数: " +a. getCars () .size ()) ;

      

    }

}

 

实体类:( set/get 方法均省略)

class People implements Cloneable { // 注意:一定要实现 Cloneable 接口,否则不支持 clone()

    byte sex ;

    String name ;

    int age ;

   

    Room room ;

    List < Car > cars ;

 

    People (){}

   

    People ( byte sex , String name , int age ){

       this . sex =sex ;

       this . name =name ;

       this . age =age ;

    }

   

    public Object clone (){// 注意 :你不能建立一个私有或默认范围克隆;你只能提高忽略时的可见性

       try {

           return super . clone () ;

       } catch ( CloneNotSupportedException e ) {

           // TODO Auto-generated catch block

           e. printStackTrace () ;

           return this ;

       }

    }

}

class Car {

    String carType ;

    String carName ;

    。。。

}

 

class Room {

    String name ;

    。。。

}

 

运行结果:

false

原本 姓名: ydj 年龄: 26 房子名字:别墅 A 拥有车子数: 2

副本 姓名: ydj 年龄: 26 房子名字:别墅 A 拥有车子数: 2

############## 修改副本的一些属性后 ##############

原本 姓名: ydj 年龄: 26 房子名字:别墅 B 拥有车子数: 3

 

分析:

为什么修改了副本,却也修改了原本?

    从上面结果可知:当修改对象副本的原始类型数据 ( 或 String) 时,不会影响原本;但修改了对象引用类型的,就会影响原本。因为这是表面的“浅拷贝”。

    拷贝分为:浅拷贝 和 深拷贝

    浅复制(浅克隆)

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

 

深复制(深克隆)

被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

 

 

3.       如何实现深拷贝:

方法 1 :

People 中所有引用的对象( Room 、 Car )每个实体都实现 Cloneable 接口,并都提供 clone ()方法实现。

然后把 People 的 clone 方法实现改为如下:

public Object deepCopy () throws CloneNotSupportedException {

       People c= ( People ) super . clone () ;

       if ( this . room != null ){

           c. room = ( Room ) this . room . clone () ;

       }

       c. cars = new ArrayList < Car > () ;

       if ( this . cars != null ){

           for ( Car i: this . cars ){

              c. cars .add (( Car ) i. clone ()) ;

           }

       }

      

       return c;

}

这样,在运行上面测试程序,我们会发现:在修改克隆后的对象时,并不会影响原对象。

 

方法 2 :

     使用序列化( Serilization )。

     People 以及所有引用的对象( Room 、 Car )每个实体都要实现 Serializable 接口。然后把 People 的 clone 方法实现改为如下:

public Object deepCopy2 () throws IOException, ClassNotFoundException {

      

       // 将对象写到流里

       ByteArrayOutputStream bos= new ByteArrayOutputStream () ;

       ObjectOutputStream dos= new ObjectOutputStream ( bos ) ;

       dos. writeObject ( this ) ;

      

       // 将对象从流里读出

       ByteArrayInputStream bis= new ByteArrayInputStream ( bos. toByteArray ()) ;

       ObjectInputStream ois= new ObjectInputStream ( bis ) ;

      

       return ois. readObject () ;

      

}

4.       总结:

使用“深拷贝”还是“浅拷贝”,取决与需要被拷贝的对象中是否引用了可变对象,取决与实际需要。

博途PLC模糊PID控制(量化因子和比例因子) 参数"量化因子和比例因子",都是为了对清晰值进行比例变换而设置的,其作用是使变量按一定比例进行放大或缩小,以便和我们的模糊论域相匹配完成一一映射。这种变换对整个系统的工作性能也是有影响的。(其实相当于额外引入了比例作用,所以说模糊PID的调节是个系统工程)。限于本人能力,文中难免出现错误和不足,欢迎大家批评和指正。博途PLC的模糊PID控制完整算法可以参看下面这篇文章博途PLC模糊PID控制详解(SCL完整源代码+参数)_RXXW_Dor的博客-优快云博客。...... 阅读详情

相关推荐

cdh zookeeper未授权访问(安全漏洞)处理

前言: 最近公司在做安全漏洞扫描。发现cdh zookeeper存在未授权访问的问题。 ZooKeeper的节点有5种操作权限: CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,这5种权限简写为crwda(即:每个单词的首字符缩写) 注:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限 ZooKeeper的身份的认证有4种方式: world:默认方式,相当于全世界都能访问 auth:代表已经认证通过的..

belialxing的专栏 2446

Java中的clone()和cloneable

Shallow Copy和Deep Copy浅拷贝和深拷贝是两个比较通用的概念。浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递...

学游泳的鱼 155

ALTERA MAX10 FPGA 串口远程升级实战:从原理到烧录的避坑指南

本文详细解析了ALTERA MAX10 FPGA如何通过串口实现远程升级。文章从工程师实战经验出发,深入剖析了MAX10片内Flash的双镜像备份原理、CONFIG_SEL引脚启动机制,并重点介绍了使用On-Chip Flash IP核进行擦写操作的核心流程。同时,提供了从Quartus工程配置、RPD文件生成、串口协议设计到驱动代码编写的完整避坑指南,旨在帮助开发者稳定、高效地完成远程升级功能部署。

weixin_29197699的博客 273

Maven中BOM

一、BOM简介 BOM(Bill of Materials)是由Maven提供的功能,它通过定义一整套相互兼容的jar包版本集合,使用时只需要依赖该BOM文件,即可放心的使用需要的依赖jar包,且无需再指定版本号。BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。 1.1、为什么需要BOM 使用BOM除了可以方便使用者在声明依赖的客户端时不需要指定版本号外,最主要的原因...

终日思 < 须臾学 1万+

BrainVision Recorder 和 BrainVision Analyzer 2.2 安装

本篇为《EEG处理》系列博客的第二篇,该系列博客主要记录EEG信号处理的学习过程中的软件安装和学习过程,方便以后查阅。本篇为BrainVision Recorder 和 BrainVision Analyzer 2.2 的安装过程。 BrainVision Recorder 和 BrainVision Analyzer 2.2 安装安装前奏Brain Vision Analyzer分析软件 安装Brain Vision Recorder记录软件 安装推荐几款个人使用的科研软件 安装前奏 Brain V

梁小憨憨的博客 5059

ESP-01S获取网络时间踩坑全记录:AT指令调试、JSON解析乱码、时区处理,一个都不能少

本文详细记录了使用ESP-01S WIFI模块获取网络时间的完整过程,包括AT指令调试、JSON解析乱码处理以及时区转换等关键步骤。通过实战案例和代码示例,帮助开发者避开常见陷阱,实现稳定的网络时间同步功能。

weixin_30460489的博客 295

图数据库Neo4j实现人脉推荐——二度人脉

“吾尝终日而思矣,不如须臾之所学也;吾尝跂而望矣,不如登高之博见也。登高而招,臂非加长也,而见者远;顺风而呼,声非加疾也,而闻者彰。假舆马者,非利足也,而致千里;假舟楫者,非能水也,而绝江河。君子生非异也,善假于物也。” 业务需求:通过现有系统“好友关系”和“用户通讯录”数据,实现人脉推荐——二度人脉….六度人脉技术实现分析: 关系数据库(深度关联表,算死人) 图数据库(天然图关系,选择Neo4j)

终日思 < 须臾学 1万+

深入解析SSD报错“READ FPDMA QUEUED”:从诊断到修复全流程

本文深入解析了SSD报错“READ FPDMA QUEUED”的含义、成因与全流程解决方案。该错误通常指示硬盘硬件或健康状态问题。文章详细介绍了如何通过系统日志定位错误、解读关键的S.M.A.R.T.健康报告(重点关注重分配扇区计数等指标),并逐步进行硬件排查(如更换SATA数据线)、软件修复与数据抢救,最终指导用户根据诊断结果做出维修或更换SSD的决策。

weixin_29233333的博客 398

Java同步、异步相关知识点

Java同步、异步相关知识点一、关键字:thread(线程)、thread-safe(线程安全)、intercurrent(并发的)synchronized(同步的)、asynchronized(异步的)、volatile(易变的)、atomic(原子的)、share(共享)二、总结背景:一次读写共享文件编写,嚯,好家伙,竟然揪出这些零碎而又是一路的知识点。于是乎,Goog

终日思 < 须臾学 1万+

大模型实战—通义千问大模型微调

这个参数仅针对 llama 类型的模型结构,默认勾选的是 q_proj 和 v_proj,具体的名词不容易理解,我就不多说了,可以简单的认为是对模型的理解能力进行优化,一般这两个就够了。当这个值较高时,适应新任务的能力会增强,但是对基础模型的影响会比较大,有过拟合的风险,尤其是在数据量有限的情况下。为了方便测试,我在云环境也创建了一个镜像,相关的环境都配置好了,可以直接使用几个国内开源的大语言模型,比如清华智谱的ChatGLM3-6B、零一万物的Yi-34B,还有最近阿里云开源的Qwen1.5-32B。

7万+

(二)OpenClaw-连接即时通讯平台-集成飞书完整配置指南

本文详细介绍了如何将OpenClaw与飞书机器人对接,实现通过飞书聊天窗口下达指令自动执行任务的高效协作模式。主要内容包括:1)OpenClaw服务部署验证和飞书账号准备;2)在飞书开放平台创建企业自建应用、添加机器人能力、获取凭证和开通必要权限;3)OpenClaw服务端的首次配置,包括设置飞书通道参数和启动长连接。文章提供了完整的操作步骤和截图指引,帮助用户快速完成对接配置,实现AI自动化助手功能。

直到世界的尽头 2246

使用Netty搭建APP推送服务器

调用时序图如下:源码:https://github.com/Aresyi/pushServer(1)获取socket登录秘钥(登录口令):key. key的时效为1分钟,如果客户端在拿到key后,1分钟之内不执行socket登录验证的流程,则key自动生效;接口服务地址:/user/getPushKey(2)客户端拿到key后,与服务器端建立socket连接,并立即发送key到服务器。如果key过期

终日思 < 须臾学 1万+

8.26华为OD机试真题 新系统 - 仓库查询 (Java/Py/C/C++/Js/Go)

8.26华为OD机试真题 新系统 - 仓库查询 (Java/Py/C/C++/Js/Go)

算法大师! 1730

诡异的异常Cannot retry request with a non-repeatable request entity

越急越乱 越想早走,越让你走不了 场景: 昨晚,使用solrj全量同步更新索引数据……生产环境 肚子饿……家里冰箱中还有半个西瓜…异常信息如下:org.apache.solr.client.solrj.SolrServerException: IOException occured when talking to server at: http://localhost:8080/solr/sd

终日思 < 须臾学 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Solr实现站内搜索

The palest ink is better than best memory——好记性不如烂笔头。2012补记 一、需求:实现O2O公司站内商品搜索(当前是数据库Like模糊查询),提高用户体验二、方案:1) 基于Lucene自己进行封装实现。工作量大及扩展性差(除非自己很牛X,封装一个如Solr一样的),故不采用。 2) 调用Google、Baidu的API实现站内搜索。同第三方搜索引

终日思 < 须臾学 4984

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring MVC Controller的线程安全

“If you have an apple and I have an apple and we exchange these apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each o

终日思 < 须臾学 4174

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Maven项目脚手架

一、背景&amp;amp;amp;目标 当前新建项目时,配置文件往往都是从其它项目拷贝过来,拷贝时很容易踩坑,并且不容易定位问题。尤其对新人来说由于在对公司项目结构、基础中间件、配置还不了解的情况下,会浪费很多不必要的时间。故,希望通过脚手架解决此痛点,达到如下几个基本目标: 1.统一规范工程项目&amp;amp;amp;代码层次结构——约定大于配置; 2.提升工作效率——脚手架&amp;amp;amp;代码生成器&amp;amp;amp;自定义插件; 3....

终日思 < 须臾学 4057

演示springboot + mybatis或springjdbc集成CAT全链路监控

演示springboot + mybatis或springjdbc集成CAT全链路监控 一、主要资料参考 服务端部署:https://github.com/dianping/cat/blob/master/cat-doc/posts/ch4-server/README.md 总文档:https://github.com/dianping/cat/tree/master/cat-doc 二、核心...

终日思 < 须臾学 3663

使用HttpClient和Jsoup定向抓取数据

1.业务需求:从指定外网抓点货,冷启动2.站点分析:.限制IP… .需要登录…… .对登录账号有抓取频率限制………. .抓取频率过低,直接跳验证码页面………….. .验证码长度、模样(纯数字&字母数字混合)TM不固定………………..“我们能不能不抓了?“ “不行!必须得抓…” “……”这么说,此前写的爬虫,多线程、生产者—>消费者 并发抓取压根行不通。多线程毫无意义。3.使用技术:1

终日思 < 须臾学 2501

站稳马步——(1)重写 equals 和 hashCode 方法

尽管Object是一个具体的类,但是设计它主要是为了扩展。它所要的非final方法(equals hashCode toString clone和finalize)都有通用约定(general contract),因为它们被设计成要被覆盖(override)的。任何一个类,它在覆盖这些方法的时候,都有责任遵守这些通用的约定;如果不能做到这一点,其它依赖这些约定的类(例如HashMap和HashSet)就无法结合该类一起正常运行。

终日思 < 须臾学 1991

Forward(转发)和Ridrect(重定向)的区别

一:首先看看转发和重定向在Action或Servlet的使用方式:1.转发  request.getRequestDispatcher("next.jsp").forward(request,response);2.重定向response.sendRedirect("next.jsp");可见,两者是通过不同对象(接口实例应用)操作的:HttpServletRequest,

终日思 < 须臾学 1982

JSP片段

使用jspf 在开发中写jsp页面时,通常都要通过如下方式在jsp文件头部引入我们需要的标签库,如:jsp核心标签库JSTL,Struts 中的自定义标签,时而还有我们自己写的自定义标签:     如果,每个jsp页面文件中都需要数十个或更多标签,那么每个jsp文件页面中都如上引入,是不是很麻烦呢?!     今天教大家一个偷懒的办法(记得,刚开始学习软件开发时,一位老师说:有时候,

终日思 < 须臾学 1524

java代码的执行顺序

今天测试了一下java代码的执行顺序。通常,我们会认为jvm加载一个类时,首先会执行main方法,其实并不是这样的。测试一下得知,真正执行顺序如下:static变量—>Static代码块—> mani()—>实例变量—>代码块—>构造函数       JVM只为静态分配一次内存,在加载类的过程中首先找带static的,为其内存分配 测试代码:package test;/

终日思 < 须臾学 1317

站稳马步——(5)java集合框架整理A

java集合框架整体概述—— 真的不用学习“数据结构”吗?

终日思 < 须臾学 1179

在Codex 让AI模型 拥有长期智能记忆

本文介绍Claude-Mem V15新功能——智能记忆召回,解决AI遗忘、重复提示、执行不一致等问题。通过本地部署claude-mem,实现自动记录决策(如数据库选型)、跨会话智能召回,支持记忆写入、检索、遗忘全流程闭环。相比传统记忆方案,其基于Hooks自动捕获工具调用,结构化存储,可追溯、可共享、可清理,显著提升工程效率与协作一致性,是长期项目中理想的“工作黑匣子”与“工程脑”。

米莱虾 262

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 115
上一篇: 站稳马步——(1)重写 equals 和 hashCode 方法
下一篇: 站稳马步——(3)java比较器——Comparable和Comparator
易德军
博客等级 码龄19年 134粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值