10 覆盖 equals 时请遵守通用约定

类的每个实例都只与它自制相等。满足其中任何一个条件

  • 类的每个实例本质上都是唯一的。
  • 类没有必要提供“逻辑相等(logical equality)的测试功能”
  • 超类覆盖了equals,超类的行为对于这个类也是合适的。
  • 类是私有的,或者是包级私有的,可以确定它的 equals 方法永远不会被调用

在覆盖 equals 方法的时候,必须要遵守它的通用约定

  • 自反性( reflexive 对于任何非 null 的引用值 equals(x )必须返回 true
  • 对称性( symmetric ):对于任何非 null 的引用值 ,当且仅当 y.equals(x )返true 时,x.equals(y )必须返回 true
 @Override public boolean equals(Object o) {
        return o instanceof CaseInsensitiveString &&
                ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
    }
  • 传递性( transitive 对于任何非 null 的引用值 ,如果 x.equals(y )返回true ,并且 y.equals(z )也返回 true ,那么 x.equals(z )也必须返回 true
  • 一致性( consistent 对于任何非 null 引用值 ,只要 equals 的比较操作在对象中所用的信息没有被修改,多次调用 x.equals(y )就会一致地返回 true,或者一致地返回 false。 或者一致地返回 false对于任何非 null 的引用值 x, x.equals (null )必须返回 false。
  • 非空性

实现高质量equals方法的诀窍

  • 使用==操作符检查“参数是否为这个对象的引用”
  • 使用 instanceof 操作符检查“参数是否为正确的类型”
  • 把参数转换成正确的类型
  • 对于该类中的每个“关键”( significant )域,检查参数中的域是否与该对象中对应的域相匹配
 @Override public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber)o;
        return pn.lineNum == lineNum && pn.prefix == prefix
                && pn.areaCode == areaCode;
    }
posted @ 2020-03-03 17:00  flank2019  阅读(88)  评论(0)    收藏  举报