本章讲述何时以及如何覆盖这些非final的Object方法
8,覆盖equal时请遵守通用的约定
- 自反性 对象必须等于自身。
- 对称性 a.equal(b) == b.equal(a) = ture
- 传递性 a == b b == c -> a == c 要注意超类
- 一致性 没有修改的话相等永远相等。
- 非空性 所有的对象都必须不等于null。要有null判断和类型判断
实现诀窍:
- 使用==操作符检查,如果是直接返回true,性能优化。
- 使用instanceof检查参数类型,如果不是返回false。有些情况下,在实现接口的类之间进行比较,那么就使用接口。
- 把参数转为正确的类型。
- 对于该类的关键域,检查参数中的域是否与该对象中对应的域相匹配。如Float.compare,Double.compare。要警惕null。要先比较最可能不一致的域。
- 当编写完equal方法之后,问自己三个问题:它是否堆成的,传递的,一致的。
告诫:
- 覆盖equal总要覆盖hashCode.
- 不要企图让equal方法过于智能。
- 不要将equals方法中的Object对象替换成其他类型。它并没有覆盖Object.equals,当然重载覆盖返回值相同也行。
9,覆盖equal总要覆盖hashCode
相等的对象必须具有相等的散列码。如果不覆盖hashCode,会使该类无法结合所有基于散列的集合一起工作,如HashMap。
10.始终要覆盖toString
被返回的字符串应该是一个简洁的,但信息丰富,并且易于阅读的表达方式。
提供好的toString实现可以使类用起来更加舒适。
如果指定返回格式,要注意扩展类后对toString的影响
11,谨慎的覆盖clone
如果用一个公共方法覆盖了非final类中的clone方法,则应该返回一个通过super.clone而得到的对象。
实际上,clone方法就是另一个构造器;你必须确保它不会伤害到原始的对象,并正确的创建被克隆对象中的约束条件。但final对象会有问题。
注意
可以肯定的说,其他接口都不应该扩展这个接口,为了继承而设计的类也不应该实现这个接口。
12,考虑实现Comparable接口
与本章的其他方法不同,compareTo方法并没有在Object中声明。一旦实现了Comparable接口,它就可以跟许多泛型算法以及依赖于改接口的集合实现进行协作。
compareTo方法的通用约定与equals方法的相似。compareTo是比较,当equals返回相等时,一般compareTo也要相等。