第 10 条:覆盖 equals 时请遵守通用约定
- 自反性 - 对象必须等于其自身
- 对称性 - 任何两个对象对于它们是否相等的问题都必须保持一致,Timestamp 违反了,不值得效仿
- 传递性 - 如果对象 A 等于B,B 等于 C,那么 A 一定等于 C
- 一致性 - 相等的对象永远相等,不相等的对象永远不相等
- 非空性 - 所有的对象都必须不等于 null
第 11 条:覆盖 equals 时总要覆盖 hashCode
- 程序一次执行期间,只要对象的 equals 比较用到的信息没有被修改,则对该对象调用多次 hashCode 都必须返回同一值
- 程序多次执行过程,每次执行返回的 hashCode 可以不一致
- 相等的对象必须有相等的散列码
- 不相等的对象不一定要产生不同的散列码,但是通常倾向于为不相等对象产生不相等的散列码
注意,如果一个类是不可变的,同时计算散列码开销也大,则可把散列码缓存在对象内部!不要试图从散列码计算中排除掉一个对象的关键部分来提高性能!
第 12 条:始终要覆盖toString
java.lang.Object 提供了 toString 方法的一个实现:类名 + ‘@’ + 散列码无符号 16 进制表示!
无论是否指定格式,都为 toString 返回值中包含的所有信息提供一种编程式的访问途径!如果没有,则会迫使程序员编写额外代码解析字符串,既降低性能,又容易解析出错导致系统不稳定!
第 13 条:谨慎地覆盖 clone
Object 的 clone 方法是受保护的!Cloneable 接口没有包含任何方法!Cloneable 改变了超类中受保护的方法的行为!对于实现了 Cloneable 的类,我们总是希望它提供一个功能适当的公有的 clone 方法!此方法首先调用 super.clone,然后修正任何需要修正的域!
实现对象拷贝更好的办法
- 拷贝构造器 - 唯一参数类型是包含该构造器的类,
public Yum(Yum yum);
- 拷贝工厂 -
public static Yum newInstance(Yum yum);
第 14 条:考虑实现 Comparable 接口
包含 compareTo 方法的对象与指定对象比较,当该对象小于、等于或者大于指定对象时,分别返回一个负整数、零或者正整数!compareTo 要满足自反性、对称性和传递性!
注意,比较整数基本类型域可使用关系操作符<和>,浮点域可使用 Double.compare 或者 Float.compare!
通常在 compareTo 中为了简化代码,会以两数作差表示比较大小的结果,这种方法有风险!记住!一个有符号的 32 位的整数还没有大到足以表达任意两个32位整数的差!如一个很大的正整数减去一个很大负整数将会溢出,并返回一个负值,导致错误结果!