effective java (8) 覆盖equals时请遵守通用约定

时间:2021-10-07 16:15:46

一般java的一个对象会由Jvm给于一个id,这个id是系统唯一的。如果不覆盖Object.equals()方法,则对象相等会比较这个id。

一般一下4中情况,可以不覆盖equals方法:

1. 对象本质唯一,比如Thread。

2. 不关心对象是否逻辑相等,比如Random。

3.超类已经覆盖,且子类可以使用新的equals方法。

4.equals方法不会被调用,比如私有类

Object.equals()方法在覆盖时,需要满足一下5个通用约定:自反性、对称性、传递性、一致性、任意非null对象与null值操作返回false。

为了实现这些要求,可以用定义以下流程来完成一个高质量的equals方法:

1. 使用==判断对象是否引用相等,如果相等,可以直接返回true

2. 用instanceof检查类型是否相等,如果不等,直接返回false

3. 对比每个关键域,任意不相等,返回false。最终返回true。

另外,有几点需要注意,

首先,覆盖equals必须同时覆盖hashCode方法。

其次,不要让equals过于智能,比如分析让File.equals()去文件链接符号。equals的关注点应该在java对象的逻辑相等上。

不要将equals(Object o)中的Object类型参数 改成其他类型——那个是重载,不是覆写。要防止的重载的话,可以使用@Override注释。