对所有对象都通用的方法

第 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位整数的差!如一个很大的正整数减去一个很大负整数将会溢出,并返回一个负值,导致错误结果!

Author: iMine
Link: https://imine141.github.io/2020/07/25/Effective%20java/%E5%AF%B9%E4%BA%8E%E6%89%80%E6%9C%89%E5%AF%B9%E8%B1%A1%E9%83%BD%E9%80%9A%E7%94%A8%E7%9A%84%E6%96%B9%E6%B3%95/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.