Effective Java笔记(13)谨慎地覆盖 clone

告别编译噩梦:Vcpkg+Cmake一站式集成Tesseract-OCR C++开发环境(Windows) 本文详细介绍了如何在Windows系统上使用Vcpkg和CMake快速集成Tesseract-OCR C++开发环境,解决传统编译过程中的依赖问题。通过一键安装和自动化配置,开发者可以高效搭建OCR识别系统,支持中英文识别,并提供了常见问题的解决方案和进阶技巧。 阅读详情

        Cloneable 接口的目的是作为对象 的 一个 mixin 接口( mixin interface ) ,表明这样的对象允克隆( clone ) 。 遗憾的是,它并没有成功地达到这个目的 。 它的主要缺陷在于缺少一个 clone 方法, 而 Object 的 clone 方法是受保护的 。 如果不借助于反射( reflection) ,就不能仅仅因为一个对象实现了 Cloneable ,就调用 clone方法 。 即使是反射调用也可能会失 败 ,因为不能保证该对象一定具有可访问的 clone 方法 。 尽管存在这样或那样的缺陷,这项设施仍然被广泛使用,因此值得我们进一步了解 。 本条目将告诉你如何实现一个行为良好的 clone 方法,并讨论何时适合这样做,同时也简单地讨论了其他的可替代做法 。

        既然 Cloneable 接口并没有包含任何方法,那么它到底有什么作用呢?它决定了 Object中受保护的 clone 方法实现的行为:如果一个类实现了 Cloneable,Object 的 clone方法就返回该对象的逐域拷贝,否则就会抛出 CloneNotSupportedException 异常 。

        虽然规范中没有明确指出,事实上,实现 Cloneable 接口的类是为了提供一个功能适当的公有的 clone 方法 。 为了达到这个目的,类及其所有超类都必须遵守一个相当复杂的、不可实施的,并且基本上没有文档说明的协议 。 由此得到一种语言之外的(extralinguistic)机制:它无须调用构造器就可以创建对象 。

        实际上,clone 方法就是另一个构造器; 必须确保它不会伤害到原始的对象, 并确保正确地创建被克隆对象中的约束条件( invariant ) 。

        就像序列化一样,Cloneable 架构与引用可变对象的 final 域的正常用法是不相兼容的, 除非在原始对象和克隆对象之间可以安全地共享此可变对象 。

        克隆复杂对象的一种办法是,先调用 super. clone 方法,然后把结果对象中的所有域都设置成它们 的初始状态( initialstate ),然后调用高层( higher-level )的方法来重新产生对象的状态。 这种做法往往会产生一个简单、合理且相当优美的clone 方法,但是它运行起来通常没有“直接操作对象及其克隆对象的 内部状态的 clone方法快 。 虽然这种方法干脆利落,但它与整个Cloneable 架构是对立的,因为它完全抛弃了 Cloneable 架构基础的逐域对象复制的机制 。

像构造器一样,clone 方法也不应该在构造的过程中,调用可以覆盖的方法 。 如果 clone 调用了一个在子类中被覆盖的方法,那么在该方法所在的子类有机会修正它在克隆对象中的状态之前,
该方法就会先被执行,这样很有可能会导致克隆对象和原始对象之间的不一致 。

        Object 的 clone 方法被声明为可抛出 CloneNotSupportedException 异常,但是,覆盖版本的clone 方法可以忽略这个声明 。 公有的 clone 方法应该省略 throws 声明 ,因为不会抛出受检异常的方法使用起来更加轻松 。

        为继承设计类有两种选择,但是无论选择其中的哪一种方法,这个类都不应该实现 Cloneable 接口 。 你可以选择模拟 Object 的行为 :实现一个功能适当的受保护的 clone 方法,它应该被声明抛出 CloneNotSupportedExceptio口异常 。 这样可以使子类具有实现或不实现 Cloneable 接口的自由,就仿佛它们直接扩展了 Object一样 。 或者,也可以选择不去实现一个有效的 clone 方法,并防止子类去实现它,只需要提供下列退化了的 clone 实现即可。

        还有一点值得注意 。 如果你编写线程安全的类准备实现 Cloneable 接口,要记住它的 clone 方法必须得到严格的同步,就像任何其他方法一样 。Object的 clone 方法没有同步,即使很满意可能也必须编写同步的 clone 方法来调用 super.clone (),即实现 synchronized clone ()方法 。

        简而言之,所有实现了 Cloneable 接口的类都应该覆盖 clone 方法,并且是公有的方法,它的返回类型为类本身 。 该方法应该先调用 super.clone 方法,然后修正任何需要修正的域 。 一般情况下,这意味着要拷贝任何包含内部“深层结构”的可变对象,并用指向新对象的引用代替原来指向这些对象的引用 。 虽然,这些内部拷贝操作往往可以通过递归地调用 clone 来完成,但这通常并不是最佳方法 。 如果该类只包含基本类型的域,或者指向不可变对象的引用,那么多半的情况是没有域需要修正 。 这条规则也有例外 。 例如,代表序列号或其他唯一 ID 值的域,不管这些域是基本类型还是不可变的,它们也都需要被修正 。

        既然所有的问题都与 Cloneable 接口有关,新的接口就不应该扩展这个接口,新的可扩展的类也不应该实现这个接口 。 虽然 final 类实现 Cloneable 接口没有太大的危害,这个应该被视同性能优化,留到少数必要的情况下才使用 。 总之,复制功能最好由构造器或者工厂提供 。 这条规则最绝对的例外是数组,最好利用 clone 方法复制数组 。

【数字IC验证快速入门】26、SystemVerilog项目实践之AHB-SRAMC(6)(AHB-SRAMC SVTB Overview) 导读:作者有幸在中国电子信息领域的排头兵院校“电子科技大学”攻读研究生期间,接触到前沿的数字IC验证知识,旁听到诸如华为海思、清华紫光、联发科技等业界顶尖集成电路相关企业面授课程,对数字IC验证有了一些知识积累和学习心得。为帮助想入门前端IC验证的朋友,思忱一二后,特开此专栏,以期花最短的时间,走最少的弯路,学最多的IC验证技术知识。 文章目录一、内容概述二、AHB-SRAMC 验证计划 一、内容概述 AHB-SRAMC 验证计划 AHB-SRAMC 验证平台的架构图 AHB-SRAMC 验证平台的代. 阅读详情

相关推荐

一文详解心电图(ECG)监测原理

介绍心电图的监测原理,从心电信号产生、获取到心电图的基本组成

m0_50146396的博客 3288

《Effective Java》阅读笔记 11谨慎地覆盖clone

1.序 Object 中 clone 方法的定义是: protected native Object clone() throws CloneNotSupportedException; 调用clone()方法需要对象实现Cloneable接口,该接口决定了Object中受保护的clone方法的实现行为: 如果一个类实现了Cloneable接口,Object的clone方法返回该对象的逐域拷贝; 如果一个类未实现Cloneable接口,则该对象就会抛出CloneNotSupportedException

weixin_41563161的博客 332

[亚信线上教学] AX58100: EtherCAT从站设备仿真功能设计教学

什么情况需要开启EtherCAT从站设备仿真功能呢? 一般来说, 当EtherCAT从站产品,不需要使用额外的微控制器介入,或使用不具备EtherCAT从站通讯协议栈的微控制器一同协作的情况下,就必须开启EtherCAT从站设备仿真功能,这样EtherCAT主站才能够正常设置从站设备的工作状态. 亚信AX58100 EtherCAT从站控制芯片的优点 AX58100 EtherCAT从站控制器, 集成2个百兆以太网Phis, 并支持一些额外的控制接口, 例如脉冲宽度调变, 增量, 霍尔编码器, .

allanchou1的专栏 7423

《Effective Java》读书笔记09--谨慎地覆盖clone方法

一、Cloneable接口与Object.clone方法 Cloneable接口的目的是作为对象的一个mixin接口(混合型接口),表明这样的对象允许克隆(clone)。遗憾的是Cloneable接口里并没有clone方法,其实它什么方法都没有,跟Serializable接口一样,都是占着茅坑不拉屎。它只是声明该对象可以被克隆,具体行为由类设计者决定。如果类设计者忘记提供一个良好的clone方法

Java Dynamic的专栏 1960

cellchat安装

cellchat

m0_65188455的博客 5448

Android软键盘系统深度解析:架构、原理与实现

Android软键盘系统深度解析:架构与实现原理 本文系统剖析了Android软键盘的核心工作机制。作为系统级输入服务,软键盘具有双重属性:既是可安装的独立应用,又深度集成于系统框架中。文章详细解读了软键盘的系统架构,包括其与InputMethodManagerService(IMMS)和WindowManagerService(WMS)的交互机制,以及通过InputConnection实现的跨进程通信流程。同时分析了输入法窗口的特殊管理策略、布局调整模式,并深入探讨了输入预测引擎的实现原理,包括词典加载、

保持专注,保持热爱 115

《Effective Java》第11条: 谨慎地覆盖clone

一. 什么情况下能够用到clone() 当我们需要一个与原对象一模一样的副本时,并且对副本进行改动而不会影响到原对象时,需要使用到clone(). 二.深拷贝与浅拷贝 浅拷贝:浅拷贝只是单纯的对于对象的拷贝,对象属性对于其它对象的引用并没有进行拷贝(也就是说浅拷贝创建的对象和原来对象指向不同的地址空间,但是对象属性里面对其它对象的引用【引用属性】指向的还是同一...

qq_34332035的博客 406

Unity 工具 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码)

Unity 基础 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码) 目录 Unity 基础 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码) 一、简单介绍 二、实现原理 三、注意实现 四、效果预览 五、ZXing.net ( zxing.unity.dll ) 插件下载 六、实现步骤 七、关键代码 一、简单介绍 Unity 开发中,自己整理的一些游戏开发可能用到的功能,整理归档,方便游...

仙魁XAN 9824

《Effective Java》谨慎的覆盖clone()方法

首先说一些,clone()是什么?应该怎么用? clone()方法是Object类中的方法,protected修饰符修饰,用来复制对象。 下面是结果: 可以看到clone()创建了一个完全不同的对象,t2指向了一个新的在堆中的对象。使用clone()方法需要实现Cloneable接口,如果不实现的话会抛出CloneNotSupportedException,这个接口并没有什么实际意义,只...

Joseph_Geeker的博客 479

linux 基于debian/ubuntu AB系统适配(二)-updateEngine移植

其实A/B系统的原理很简单,大部分的工作都集中在uboot上,rootfs只是起到一个辅助的作用,但这个作用也就必不可少的。你会发现在这个其中并没有kernel的参与。

badbayyj的博客 1033

Laser-Marking 激光振镜打标机的开源代码 - 下载 - 搜珍网

为了方便开发者的使用和定制化需求,我们在这里提供激光振镜打标机的开源代码,并附带详细的描述。首先,让我们来了解一下激光振镜打标机的基本原理。振镜系统由两个可移动的反射镜组成,可以控制激光束在水平和垂直方向上的偏转角度,从而实现对工件的精确控制。通过这段开源代码,开发者可以根据自己的需求对激光振镜打标机进行二次开发和定制化。你可以修改振镜角度、打标速度等参数,也可以添加其他功能,例如自动识别和追踪等。首先,我们创建了一个串口对象,用于与激光振镜打标机进行通信。函数实现了对用户输入文本的打标操作。

TechProX的博客 1279

Effective Java 精简实用版

1. 使用静态工厂代替构造,clone函数 原因    1.      静态工厂具有名字                  i.          对于两个构造函数,如果参数类型和个数相同,则只能使用不同的顺序进行区分,而使用工厂函数可以为这两个构造函数指明不同的名称                 ii.          如果有多个构造函数,可考虑用静态工厂方法替换 2.

dananhai381的专栏 635

在 FreeStyle SAP UI5 应用里优雅落地 Draft 草稿机制:用 DraftManager 封装 DraftController 的一套实战套路

SAP Fiori应用中,Draft草稿机制是解决业务中断、多人协作和长表单填写等痛点的核心能力。本文提出了一套针对FreeStyle SAP UI5应用的Draft管理方案,通过封装sap.ui.generic.app.transaction.DraftController为DraftManager服务类,将复杂的草稿操作逻辑集中管理。该方案实现了草稿的创建、激活、丢弃等核心功能,使控制器只需调用简单意图式API即可完成操作,同时解决了组件化架构下的上下文切换、统一错误处理等问题。文章还详细介绍了后端Dr

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2751

《Effective Java》第13条:谨慎的覆盖clone

原文P51:克隆复杂对象的最后一种办法是,先调用super.clone方法,然后把结果对象中的所有域都设置成它们的初始状态,然后调用高层的方法来重新产生对象的状态。原文P47:如果类的clone方法返回的实例不是通过调用super.clone方法获得,而是通过调用构造器获得,编译器就不会发出警告,但是该类的子类调用了super.clone方法,得到的对象就会拥有错误的类,并阻止了clone方法的子类正常工作。因此,上一段中讨论到的put(key,value)方法要么应是final的,要么应是私有的。

TD_FAlmK的博客 698

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Effective Java – Item 13 谨慎地覆盖 clone

item13 · 谨慎地覆盖 clone Cloneable 接口的目的是作为对象的一个 mixin 接口,表明这样的对象允许克隆。但,它并没有成功地达到这个目的,它的主要缺陷在于缺少一个 clone 方法,而 Object 的 clone 方法是受保护的。 Cloneable 作用 决定了 Object 中受保护的 clone 方法实现的行为 如果一个类实现了 Cloneable 接口,O...

AlbumenJ的博客 219

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

《Effective Java》解读第13条:谨慎地覆盖clone

摘要:Java的clone方法存在诸多设计缺陷,不推荐直接使用。主要问题包括:语义不明确(深/浅拷贝)、绕过构造器、Cloneable接口异常机制不合理、与final域冲突等。若必须实现clone,应遵循规范:实现Cloneable接口,调用super.clone()进行浅拷贝,并递归处理可变对象字段。更推荐的替代方案是使用拷贝构造器或静态工厂方法,它们更灵活安全,能避免clone的固有缺陷,尤其适合处理含引用类型字段的对象复制需求。

Cosmoshhhyyy的博客 481

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Effective Java 【对于所有对象都通用的方法】第13条 谨慎地覆盖clone

目录谨慎地覆盖cloneCloneable接口并没有包含任何方法,那么它到底有什么作用呢?Object类中的clone()方法如何重写好一个clone()方法1.对于数组类型我可以采用clone()方法的递归2.如果对象是非数组,建议提供拷贝构造器(copy constructor)或者拷贝工厂(copy factory)3.如果为线程安全的类重写clone()方法4.如果为需要被继承的类重写clone()方法总结 谨慎地覆盖clone Cloneable接口地目的是作为对象的一个mixin接口(详见第20

zhangxiaoxiao9527的博客 377

《Effective Java》学习笔记13 Override clone judiciously

本栏是博主根据如题教材进行Java进阶时所记的笔记,包括对原著的概括、理解,教材代码的报错和运行情况。十分建议看过原著遇到费解地方再来参考或与博主讨论。致敬作者Joshua Bloch和各路翻译者们,以及为我提供可参考博文的博主们。 谨慎地重新clone()方法 Cloneable接口 Cloneable接口与其他接口不同,它里面啥都没有,仅仅是为了表示该类可以被克隆。所有单独只有它自己,还...

欢迎访问 花落的速度 的博客 581

快速带你看完《Effective Java》—— 对象通用方法篇

文章目录10 覆盖equals时要遵守通用约定11 覆盖equals时总要覆盖hashCode12 始终要覆盖toString13 谨慎地覆盖clone14 考虑实现Comparable接口 豆瓣评分9.8的图书《Effective Java》,是当今世界顶尖高手Josh Bloch的著作,在我之前的文章里我也提到过,编程就像练武,既需要外在的武功招式(编程语言、工具、中间件等等),也需要修炼心法(设计模式、源码等等)学霸、学神OR开挂 我个人在Java领域也已经学习了近5年,在修炼“内功”的方面也通过各

如切如磋,如琢如磨 1225

Effective Java笔记

文章目录第二章:创建和销毁对象第1条: 静态工厂方法代替构造器优势1:它们有名称优势2:不必在每次调用它们的时候都创建一个新对象。优势3:它们可以返回原返回类型的任何子类对象。优势4:所返回的对象的类可以随着每次调用而发生变化优势5:方法返回的对象所属的类,在编写包含该静态方法的类时可以不存在。缺陷1:类如果不含公有或保护的构造器。就不能被子类化(继承)。#### 缺陷2:没有统一的标准。相对构造函数较难查明。 第二章:创建和销毁对象 第1条: 静态工厂方法代替构造器 优势1:它们有名称 更为清楚。 优势2

weixin_44677487的博客 535

effective java 第13条:关于覆盖Clone

1.不可变的类永远不要提供clone方法 (final) 2.类中只包含基本类型的值或者包含一个指向不可变对象引用(String) 可以直接 指向不可变对象的引用-- String 类型的引用 不可变的对象引用-- final修饰的引用 try{ 强制转换类 A = (强制转换类)super.clone(); //A.可变对象 = 可变对象.clone 递归调用 } catch(CloneNotSupportedException e) { } 3.类中有final修饰的域,不能用Clone 4.事

D_XQY_的博客 368

Effective Java 3rd 条目13 谨慎覆写clone

Cloneable接口目的是为类作为一个混入接口,宣称它们允许克隆。不幸的是,它未能作为这个目的。它的主要缺点在于,它缺少了clone方法,而且Object的clone方法是受保护的。没有诉诸于反射(条目65),你不能调用对象的clone,仅仅因为它实现了Cloneable。甚至反射调用可能失败,因为没有保证对象有一个可获取的clone方法。尽管这个缺点和其他的缺点,这个技巧在合理的广泛使用中,所

tigershin的专栏 502

effective java 读书笔记_effective java 读书笔记

第二章:创建和销毁对象第7条:避免使用终结方法final、finally、finalize的区别:final:修饰符,关键字,可以修饰成员、方法和类,如果类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。将变量或者方法声明为final,可以保证他们在使用中不被改变。finally:一般是用于异常处理中,提供finally块来执行任何的清楚操作,try{} catch(){} ...

weixin_36383576的博客 213

《Effective Java》读书笔记,移动安全入门

equals()方法实现了等价关系。 自反性。对于任何非null的引用值x,x.equals(x)必须返回true.(对象必须等于其自身) 对称性。对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。(警惕子类父类不同的equals实现时) 传递性。对于任何非null的引用只x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equeals(z)也必须返回true。(优先使用组合

m0_66264938的博客 223

effective java

发现自己水得一比,决定把effective java的设计原则记一下笔记 1.静态工厂方法代替构造器 好处: a.有名称 比如BigIntger.probablePrime可能产生一个素数 b.不会产生新的对象 c.可以返回子类型的对象,比如Enumset的noneOf d.使代码变得简洁 Map<String, String> map = new Map<S...

newbaby2012的专栏 355

effective java读书笔记_effective java 读书笔记

第二章:创建和销毁对象第7条:避免使用终结方法final、finally、finalize的区别:final:修饰符,关键字,可以修饰成员、方法和类,如果类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。将变量或者方法声明为final,可以保证他们在使用中不被改变。finally:一般是用于异常处理中,提供finally块来执行任何的清楚操作,try{} catch(){} ...

weixin_35980011的博客 286
上一篇: Java 函数式编程(常用接口)
下一篇: Effective Java笔记(14)考虑实现 Comparable 接口
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值