标签:
这一章主要讲解Object类中的方法, Object类是所有类的父类,所以它的方法也称得上是所有对象都通用的方法
第八条 覆盖equals时需要遵守的约定
Object中的equals实现,就是直接对对象进行相等的比较:
public boolean equals(Object obj) { return (this == obj); }
那么什么时候需要覆盖equals呢?
当你的类有自己的逻辑相等,而不是对象相等时,应该自己实现equals,比如Date和Interger,他们的相等比较不仅是对象相等,需要涉及到内部值的相等,
// Integer的equals实现: public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } // Date的equals实现: public boolean equals(Object obj) { return obj instanceof Date && getTime() == ((Date) obj).getTime(); }
equals方法的实现必须满足等价关系(温习一下数学基本概念):
1.自反性。对于任何非null的引用值x,x.equals(x) 必须为true
2.对称性。对于非null的x和y,x.equals(y)推导出y.equals(x)
3.传递性。非null的xyz,x.equals(y) 并且y.equals(z),那么x.equals(z)
这里讨论了一个典型例子。自类扩展了父类,增加了新的值组件(变量),那么equals很难在父类子类之间同时生效,比如父类的equals就缺少子类的新增变量的比较,子类的equals来比较父类,父类缺少子类新增的变量。
文中提出了一种方法,基于组合优先于继承的原则,将子类独立出来,增加自己的值组件,并在子类中实现父类的实例,这样可以同时用equals比较这两部分
4.一致性。任何非null的xy,只要equals的比较操作在对象中所用的信息没有改变,多少次操作得到的值应该一样
5.非空性。一般并不需要在equals里显示的检查null == obj,因为 if (obj instanceof Integer) {}已经做了这个工作
关于写equals的几个建议:
1.优先使用==检查是否为这个对象的引用
2.使用instanceof检查参数是否为正确类型
3.equals覆盖时总要覆盖hashcode(),见第九条
4.不要让equals太智能太复杂
5.不要讲equals的参数改为其他类型,应该为Object
[Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第八 ---- ?条
标签:
原文地址:http://www.cnblogs.com/jiangz222/p/4774430.html