【第7条】在改写equals的时候请遵守通用约定

2024-04-17 22:48

本文主要是介绍【第7条】在改写equals的时候请遵守通用约定,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《第3章 对所有对象都通用的方法》


    这是我认为最有用的一章,真的该好好问问自己,这些最最基础的东西,自己都掌握吗?
    Object是个即普通又特殊的类。说它普通是因为所有的类都是由它派生来的,说它特殊是因为它是所有其他类的父类必须先了解它才能写好你自己的类。
    Object所有的非final方法,都是为改写(override)而设计的,改写方法都有明确的约定,这一章就是讲述该如何改写这些法方的。

 

【第7条】在改写equals的时候请遵守通用约定

    equals即“相等”之意,看起来改写很容易,但是实际中却容易犯错误。
equals的改写规范:
 1)自反性:x.equals(x)一定为true
 2)对称性:当且仅当x.dquals(y)为true;那么y.equals(x)也必须为true
 3)传递性:如果x.equals(y)为true,y.equals(z);那么x.equals(x)也必须为true
 4)一致性:对于任意引用值x和y,如果用于equals比较的对象信息没有被修改的话,那么多次调用x.dquals(y)返回的值是一致的
 5)对于非空引用值x,x.equals(null)一定返回false
 
    看上去这些约定都是废话,一个头脑没有问题的人,对于“相等”的理解,不会对以上五条产生任何疑问。但落实到代码上就不是这么简单了,在改写完equals方法后用一些测试代码来逐条对照检查一下是非常有必要的。
   

    一旦违反了其中一条,后果就是不堪设想的。


    比如:自反性。如果违反了“x.equals(x)一定为true”这一条。当这样的类的一个实例被放入到一个集合(collection)中后,当你通过contains方法向集合询问是否含有此实例时,集合会告诉你“没有”。为什么呢?contains方法就是靠调用放入其中的对象的equals方法来判断是包含的(编写contains方法的人认为所有的类都该有一个满足约定的equals方法)。
   
写好equals方法的“处方”:
 1)使用==操作符检查“实参是否为指向对象的一个引用”
     if (o==this)
       return true;


 2)使用instanceof操作符检查“实参是否为正确的类型”
     if (!(o instanceof MyClass))
       return false;


 3)把实参转为正确的类型
     MyClass mo = (MyClass)o;


 4)对于该类中每一个“关键(significant)”域,检查实参中的域与当前对象中对应的域值是否匹配
     if (!(this.field == null ? o.field == null : this.equals(o.field)))
     //或者写成 if(!(this.field == o.field || (this.field != null && this.field.equals(o.field)))) 对于this.field和o.field通常是相同的对象引用,会更快一些。
       return false;
     //比较下一个field
     //都比较完了
     return true;


 5)最后还要确认以下事情
   5.1)改写equals的同时,总是(必须)要改写hashCode方法(见【第8条】),这是极容易被忽略的,有极为重要的
   5.2)不要企图让equals方法过于聪明
   5.3)不要使用不可靠的资源。如依赖网络连接
   5.4)不要将equals声明中的Object对象替换为其他类型。
         public boolean equals(MyClass) 这样的声明并不鲜见,往外使程序员数小时搞不清楚为什么不能正常工作
         原因是这里是重载(overload)而并不是改写(override)(或称为覆盖、重写)
         相当于给equals又增加了一个实参类型为MyClass的重载,而实参为Object的那个equals并没有被改写,依然还是从Object继承来的最初的那个equals,所总是看不到程序员想要的效果。因为类库或其他人写的代码都是调用实参为Object型的那个equals方法的(别人又如何在事前知晓你今天写的MyClass呢?)

 

 

 

【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208

 

这篇关于【第7条】在改写equals的时候请遵守通用约定的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/913076

相关文章

青龙面板部署通用教程,含服务器、路由器、X86等部署方法

1. 拉取镜像/更新镜像 docker pull whyour/qinglong:latest 2. 删除镜像 docker rmi whyour/qinglong:latest 3. 启动容器 普通服务器 docker run -dit \-v $PWD/ql/config:/ql/config \-v $PWD/ql/log:/ql/log \-v $PWD/ql/db:

通用大模型 vs垂直大模型:AI界的“宫斗大戏”

科技圈最近可真热闹,AI大模型的“宫斗大戏”让人眼花缭乱。两个阵营:通用大模型和垂直大模型,正在上演一场激烈的“权力的游戏”。到底谁能笑到最后?咱们一起来“吃瓜”看看吧! 首先,登场的是“全能王”通用大模型。它们就像是学习成绩顶尖、体育全能的学霸,什么都懂,什么都能干。 通用大模型:全能选手看看这家伙的优势: 通用大模型就像那种考上清华北大的学霸,不管是文科还是理科,全都能拿下。从写文章到

游戏高度可配置化(一)通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解

游戏高度可配置化(一)通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解 码客 卢益贵 ygluu 关键词:游戏策划 可配置化 模块化配置 数据引擎 条件系统 红点系统 一、前言 在插件式模块化软件开发当中,既要模块高度独立(解耦)又要共享模块数据,最好的方法是有个中间平台(中间件)提供标准的接口来进行数据的交换,这在很多行业软件开发中已经广泛应用。但是,由于中间件的抽象和封

C# 唯一性进程的方法封装(Winform/WPF通用)

C#唯一进程封装 C# 唯一性进程的方法封装 public class UniqueProcess{/// <summary>/// 焦点切换指定的窗口,并将其带到前台/// </summary>/// <param name="hWnd"></param>/// <param name="fAltTab"></param>[DllImport("user32.dll")]public st

String的== 与equals详解

先来看一个面试题 结果是 false;true;false "=="来比较它们所引用的是否是同一个对象时 string 比较是否同一个对象,用== string比较字符串字面量相等用equals string 字面量创建的会写入到常量池,独立的 string new出来的会进堆,独立的 final的值在编译是就确定了 所以 此时 a+b 对编译器来说就是“ab” 没有fi

AI通用写作模版,可以在此基础上进行修改

指令 角色 作者 :你是一位自媒体爆文写作专家,负责撰写文章,具备对特定主题的深入理解和一定的写作技巧。读者 :25-55岁通用人群,对资讯新闻类感兴趣,需要易于理解且富有启发性的内容。 技能 研究能力:对特定主题进行深入研究,收集相关资料,确保内容的准确性和丰富性。写作能力:运用清晰、简洁的语言进行叙述,使文章易于阅读和理解。逻辑组织能力:合理安排文章结构,确保内容条理清晰,逻辑严密。共

【Rust日报】 2019-05-28:使用WASI对区块链进行通用计算

「嵌入式」Hawk-Rust系列:树莓派相机的驱动 #RaspberryPi Raspberry Pi提供了一组GPIO(通用输入/输出)引脚,允许您控制用于物理计算的电子组件并探索物联网(IoT)。 相机模块是Raspberry Pi的绝佳配件,它允许用户拍摄静态照片并以全高清录制视频。 HAWK是一个基于Rust的图像识别项目,它通过使用RFID卡进行用户识别和Image进行用户验证来实

textarea标签改写为富文本框编辑器KindEditor

下载 - KindEditor - 在线HTML编辑器 KindEditor的简单使用-CSDN博客 一、 Maven需要的依赖: 如果依赖无法下载,可以多添加几个私服地址:         在Maven框架中加入镜像私服 <mirrors><!-- mirror| Specifies a repository mirror site to use instead of a

通用VS垂直,谁将领跑落地新纪元?

随着人工智能技术的飞速发展,大模型已成为推动各行业智能化升级的核心力量。在这个充满挑战与机遇的领域,通用大模型与垂直大模型之间的竞争正愈演愈烈。它们各自有着不同的优势,然而究竟谁能在大模型的第一个赛点拔得头筹,领跑未来智能化进程,尚未有定论。  首先,让我们了解一下通用大模型。通用大模型具备强大的泛化能力,适用于各种不同的任务和场景,如自然语言处理、图像识别、语音识别等。这种广泛的适用性使得通

通用大模型的低代码平台——3分钟内快速搭建一个邮件提醒工具

文章目录 ⭐前言⭐node-koa开发一个发送邮件的api⭐百度智能云控制面板💖 发送邮件的组件配置💖 配置应用发布 ⭐总结⭐结束 ⭐前言 大家好,我是yma16,通用大模型的低代码平台——3分钟内快速搭建一个智能股票分析邮件提醒工具。 通用大模型和垂直大模型的区别 通用大模型是指在多个领域或任务上表现出色的大型模型,它们经过大规模的预训练和微调,具有较高的参数容