美文网首页
Item 10: Obey the general contra

Item 10: Obey the general contra

作者: 空谷幽心 | 来源:发表于2018-08-05 11:03 被阅读12次

    笔记

    • All of its nonfinal methods (equals, hashCode, toString, clone, and finalize) have explicit general contracts because they are designed to be overridden.
      生来就是被覆写的。注意阅读doc文档中的约定。

    • The easiest way to avoid problems is not to override the equals method, in which case each instance of the class is equal only to itself.

      • Each instance of the class is inherently unique.
      • There is no need for the class to provide a “logical equality” test.
      • A superclass has already overridden equals, and the superclass behavior is appropriate for this class.
      • The class is private or package-private, and you are certain that its equals method will never be invoked.
        最好不要覆写equals方法。
        一般满足这几个条件的情况下,不需要覆写:
        • 每个实例天然唯一。
        • 不需要做“逻辑相等”检查。
        • 父类的equals方法适用当前类。
        • equals方法不会被调用。这种情况可以在方法内抛异常。
    • It is when a class has a notion of logical equality that differs from mere object identity and a superclass has not already overridden equals. This is generally the case for value classes. A value class is simply a class that represents a value, such as Integer or String.
      需要覆写的情况:实现区别于实例对象相等的“逻辑相等”,且父类没有覆写equals方法。一般都是value class。

    • One kind of value class that does not require the equals method to be overridden is a class that uses instance control (Item 1) to ensure that at most one object exists with each value. Enum types (Item 34) fall into this category.
      那些要做实例控制的类,比如Enum,不在此列。

    • The equals method implements an equivalence relation. It has these properties:

      • Reflexive
      • Symmetric
      • Transitive
      • Consistent
      • “non-nullity.” For any non-null reference value x, x.equals(null) must return false.
        相等在数学上的表述就是具备下述五个规定:
        • 反射性。x.equals(x) == true。
        • 对称性。if x.equals(y) == true,then y.equals(x)。
        • 传递性。if x.equals(y) == true and y.equals(z) == true, then x.equals(z)
        • 一致性。假设两个对象没有影响equals方法的信息变更,多次调用equals方法的结果需相同,保持前后一致性。
        • 不等于null
    • Putting it all together, here’s a recipe for a high-quality equals method:

      1. Use the == operator to check if the argument is a reference to this object.
      2. Use the instanceof operator to check if the argument has the correct type.
      3. Cast the argument to the correct type.
      4. For each “significant” field in the class, check if that field of the argument.
      5. When you are finished writing your equals method, ask yourself three questions: Is it symmetric? Is it transitive? Is it consistent?
        ide生成的equals方法就是遵循这些步骤来判断相等的。

    matches the corresponding field of this object.

    • Here are a few final caveats:

      • Always override hashCode when you override equals (Item 11).
      • Don’t try to be too clever. If you simply test fields for equality, it’s not hard to adhere to the equals contract. If you are overly aggressive in searching for equivalence, it’s easy to get into trouble. It is generally a bad idea to take any form of aliasing into account.
      • Don’t substitute another type for Object in the equals declaration. Consistent use of the Override annotation, as illustrated throughout this item, will prevent you from making this mistake (Item 40).
        警告:
        • 记得覆写hashCode方法。
        • 不要自作聪明。比较对象的属性就好,不要做其他形式的约等于。
        • 覆写方法记得加上Override标记。不要替换接口的参数为具体的类型,那样会导致不能覆写接口。
    • An excellent alternative to writing and testing these methods manually is to use Google’s open source AutoValue framework。IDEs, too, have facilities to generate equals and hashCode methods。
      偷懒的方法。

    • In summary, don’t override the equals method unless you have to: in many cases, the implementation inherited from Object does exactly what you want. If you do override equals, make sure to compare all of the class’s significant fields and to compare them in a manner that preserves all five provisions of the equals contract.
      不要轻易覆写equals方法。覆写的时候注意比较所有重要的属性,确保他们都满足equals的五个规定。

    理解与思考

    实践

    1. ide提供的默认方法已经非常好用了。比如idea里的实现:
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;  // 检查实例相等
            if (o == null || getClass() != o.getClass()) return false; // 检查非null,是否属于同类
            TechDemo techDemo = (TechDemo) o; // 
            return a == techDemo.a && // 比较关键属性
                    b == techDemo.b &&
                    c == techDemo.c;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(a, b, c);
        }
    

    相关文章

      网友评论

          本文标题:Item 10: Obey the general contra

          本文链接:https://www.haomeiwen.com/subject/iwzvvftx.html