先介绍一下Object的equal作用,==代表物理上的相等,equal代表逻辑上的相等,Object的equal的方法其实等同于==,这是因为它的逻辑是“如果对象物理相等,那么它们就逻辑相等”。

1.何时不需要覆盖

1.如果每个实例的本质是唯一的,也就是说只有自己才会等于自己,那么它的equal方法应该相当于它的==,所以它从Object继承过来的方法刚好满足条件了,不需要覆盖。

2.不关心它的“逻辑相等”,既然都不关心了,那还写什么?

3.超类覆盖的equal方法,对子类同样适用的情况下,就不用覆盖了。比如Set实现了从AbstractSet继承的方法,所以它不用去覆盖了。

2.何时需要覆盖

1.有的类的equal永远也不会调用的情况,那么应该覆盖equals方法,让它在调用时抛出错误。

2.如果希望定义特有的”逻辑相等”的情况,可以覆盖equals,比如定义市民类,如果两个市民的身份证字段相等,那么两个市民类相等,这样的逻辑。

3.覆盖需要遵守的约定

在覆盖equals方法时,必须遵守它的通用约定:

1)自反性: x.equals(x) 必须返回true 。实例自身必然逻辑相等。

2)对称性: x.equals(y) 与 y.equals(x) 返回结果应该相同,同为true或者同为false

3)传递性: x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)应该返回true。

4)一致性: 只要比较的实例对象的关键属性值没有改变 ,那么无论调用多少次equals方法返回的结果都应该相同,一致。

5)对于非null的x实例,x.equals(null) 永远返回false。

这一章的内容十分地充实,这里,我只能总结一下书中重要的内容:

1.不要企图让一个类和一个它的非子类进行equal对比,比如 市民类.equal(String identity),
希望只要市民的身份证号等于字符串类型的identity就返回true,这样是不可行的,因为必然会违反对称性,除非你能去修改String类?

2.我们无法在扩展可实例化的类的同时,既增加新的值组件,同时又保留equal约定。
也就是遇到可实例化的父类和子类,而且子类扩展了父类的问题时,会遇到很尴尬的问题,这里应该认真看一下书~

书中写到了父类和子类的各种纠缠~解决的一种方法,也可以说是权宜之计,就是割断父子关系。。
也就是利用复合优于继承的原则;原来的子类不是扩展了父类吗,那么我让父类成为原来子类的一个私有域,利用复合的方式组装一个类出来。既然不存在父子关系了,父子进行对比产生的种种纠缠也就不复存在了。

书中也有举到一个很有意思的例子,TimeStamp对Date进行扩展,增加了nanoseconds域,由于上面的规则“我们无法在扩展可实例化的类的同时,既增加新的值组件,同时又保留equal约定”,所以设计师也无法进行正确的操作,于是TimeStamp有个免责声明,告诫开发者不要同时使用TimeStamp和Date,也就是不让程序员纠缠在父子的问题上了。

这里有个里式替换原则,可以注意一下:一个类型的任何重要属性也将适用于它的子类型,因此为该类型编写的任何方法,在他的子类型也应该同样运行得很好

4.如何使用?

1.先用“==”操作符号判断“参数是否为这个对象的引用”,如果是,那直接返回true。
这其实是一种性能优化,不进行这个操作也会得到一样的结果,所以需要根据每次比较的代价判断是否先用“==”,代价大就需要优化。

2.用instanceof检查“参数是否为正确的类型”。

3.再将参数object对象转成正确的类型。

4.自己定义“逻辑相等”。

5.写完有仔细思考有没有满足对称性,传递性,一致性。

例子:

public class Citizen {private String name ;private String Identity;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getIdentity() {return Identity;}public void setIdentity(String identity) {Identity = identity;}@Overridepublic boolean equals(Object obj) {if(this == obj) {return true;}if(!(obj instanceof Citizen)) {return false;}Citizen citizen = (Citizen)obj;return this.getIdentity().equals(citizen.getIdentity());}}

这里的 先用“==”操作符号判断“参数是否为这个对象的引用” 可以不需要。

Effective Java之覆盖equal时要遵守通用约定(八)相关推荐

  1. Effective Java 对于所用对象都通用的方法 8.覆盖equals时请遵守通用约定.txt

    对于eclipse覆盖equals方法就是Alt+Shift+S,而AS就是Alt+Insert.覆盖很简单,可是却容易导致错误,而且后果很严重.最容易避免的方法就是不覆盖,这样类就只与他自身相等. ...

  2. Effective Java 读书笔记(七):通用程序设计

    Effective Java 读书笔记七通用程序设计 将局部变量的作用域最小化 for-each 循环优于传统的 for 循环 了解和使用类库 如果需要精确的答案请避免使用 float 和 doubl ...

  3. Effective Java:对于全部对象都通用的方法

    前言: 读这本书第1条规则的时候就感觉到这是一本非常好的书.可以把我们的Java功底提升一个档次,我还是比較推荐的.这里我主要就关于覆盖equals.hashCode和toString方法来做一个笔记 ...

  4. Effective Java:对于所有对象都通用的方法

    前言: 读这本书第1条规则的时候就感觉到这是一本很好的书,可以把我们的Java功底提升一个档次,我还是比较推荐的.这里我主要就关于覆盖equals.hashCode和toString方法来做一个笔记总 ...

  5. 《Effective Java》 第二讲:对于所有对象都通用的方法

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 上接<Effective Java> 第一讲:创建和销毁对象 八.覆盖 equals 时 ...

  6. Effective Java(第3版) 90条经验法则

    目录 第2章 创建和销毁对象 第1条:用静态工厂方法替代构造器 第2条:遇到多个构造器参数时要考虑使用构建器 例子 使用 第3条:用私有构造器或者枚举类型强化Singleton属性 例子 使用 第4条 ...

  7. 《Effective Java》中文版第3版 读书笔记

    评论中有电子档资源哦  ^_^ 第1章引言 第2章创建和销毁对象 第1条:用静态工厂方法代替构造器 静态工厂方法与构造器不同的第一大优势在于,它们有名称.  静态工厂方法与构造器不同的第二大优势在于, ...

  8. Effective Java 读书笔记----第三章

    第三章 对于所有通用的方法 主要讲的是对Object类的非final方法(equals,hashCode,toString,clone和finalize)覆盖的一些规则 1.覆盖equals时请遵守通 ...

  9. 《Effective Java》读书笔记

    引言 1 代码应该被重用 ,而不是被拷贝. 2 错误应该尽早被检测出来,最好是在编译时刻. 3 接口.类.数组是引用类型(对象), 基本类型不是 第二章 创建和销毁对象 1 考虑用静态工厂方法代替构造 ...

最新文章

  1. Android HttpClient post MultipartEntity - Android 上传文件
  2. Window ChromeDriver(简单4步完成)
  3. 10个利用Eclipse调试Java的常见技巧
  4. python死锁案例_python避免死锁方法实例分析
  5. 【数据库bug修复】——Authentication plugin ‘caching_sha2_password‘ is not supported
  6. 计算机系统基础:设备管理采用的相关技术知识笔记
  7. git啊,你让我好费劲啊
  8. docker mysql5.7.19_Docker19.03.13下安装Mysql57
  9. VS2008都出來了﹐看來我們升級VS2005的計划要改了。
  10. 问题五:C++中const是干嘛用的
  11. FineReport帆软报表使用入门
  12. 测试人员的绩效考核,看看你有哪些没做好
  13. “立字据,你们这群混蛋!”
  14. python123货币转换器_python货币转换
  15. matlab shading 的用法说明
  16. Pycharm远程调试服务器代码出错:[Errno 2] No such file or directory
  17. spring boot(banner在线生成)
  18. CAD二次开发之选择集过滤
  19. mysql C openmp_OpenMP: sections分段并行 | 学步园
  20. 第十届“泰迪杯”比赛B题解题思路及代码论文

热门文章

  1. 关于多线程的一点感想
  2. Wireshark 抓包分析 RTSP/RTP/RTCP 基本工作过程
  3. OpenShift 与 OpenStack:让云变得更简单
  4. MySQL 备份与主从复制
  5. 小短文 | 高并发系统,如何计算并发量和峰值数据?
  6. 只会使用 WaitGroup?你应该学习下 ErrGroup!
  7. 我就改了一行代码,为什么就全超时了?
  8. 08 / LiveVideoStack主编观察:开源RTC的机会来了吗?
  9. TikTok测试三分钟视频、Reddit首次公布DAU、谷歌解雇人工智能领头人、年度最受欢迎应用|Decode the Week...
  10. 槽点才是G点,LiveVideoStack主编是如何吐槽内容的?