对于所有对象都通用的方法
- 所有对象都通用的方法:
equals
hashCode
toString
clone
finalize
覆盖equals时请遵守通用约定
- 期望的结果:
- 类的每一个实例本质上都是唯一的
- 这些类没有必要提供“逻辑相等”的测试功能
- 超类已经覆盖了
equals
,超类的行为对于这个类也是合适的
- 类是私有的,或者是包级私有的,可以确定其
equals
方法永远不会被调用
- 需要重写
equals
的时候:类具有自己特有的逻辑相等
- 重写
equals
的约定:
- 自反性:
x.equals(x)=true
- 如果违反了自反性,在使用集合的
contains
方法时会出现问题
- 对称性:
x.equals(y)=y.equals(x)
- 传递性:
x.equals(y)=y.equals(z)=x.equals(z)
- 一致性:
x.equals(y)
总是一致的返回一个结果
x.equals(null)=false
- 实现
equals
方法的诀窍:
- 使用
==
操作符检查“参数是否为这个对象的引用”
- 使用
instanceof
操作符检查“参数是否为正确的类型”
- 把参数转换成正确的类型
- 对于该类中的每一个关键属性进行逐个检查
- 一些告诫:
- [[#覆盖
equals
时总要覆盖hashCode
]]
- 不要企图让
equals
过于智能
- 不要将
equals
声明中的Object
对象替换为其他类型
- 使用IDE生成
equals
方法
覆盖equals
时总要覆盖hashCode
- 相等的对象(
equals
)必须具有相同的散列码
- 一个好的散列函数:不同对象产生不相同的散列码
- 简单的解决方法:
- 声明一个
int result
,将其初始化为对象中第一个关键域的散列码c
- 接下来计算其他关键域的散列码:
- 基本类型:使用
Type.hashCode()
- 对象引用:递归调用其中的
hashCode()
- 数组:对其中的每一个元素对计算一次散列码
- 合并到
result
中
- 返回
result
- 不要试图从散列码计算中排除掉一个关键域来提高性能
始终要覆盖toString
方法
- 默认的
toString
方法:类名称@散列码
- 我们所需要的
toString
方法:具有简洁的信息,并且易于阅读
- 返回的
String
中应该包含所有重要的信息
谨慎的覆盖clone
- 如果一个类实现了
Cloneable
接口,那么Object clone()
方法就会返回该对象的逐域拷贝,否则抛出CloneNotSupportException
异常
- 实现
Cloneable
接口的类是为了提供一个功能适当的公有clone
方法
- 不可变的类永远都不应该提供
clone
方法
- 对象拷贝的更好方法是提供一个拷贝构造器或拷贝工厂