2.Methods Common to All Objects--Effective Java 2nd Ed学习笔记

Item 8: Obey the general contract when overriding equals

Equivalence relation(equals必须满足的性质):

Reflexive: For any non-null reference value x, x.equals(x) must return true.
Symmetric: For any non-null reference values x and y, x.equals(y) must return true if and only if y.equals(x) returns true.
Transitive: For any non-null reference values x, y, z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) must return true.
Consistent: For any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) must return false.

不满足对称性的例子:

Once you’ve violated the equals contract, you simply don’t know how other objects will behave when confronted with your object.

为了消除该问题,必须避免让CaseInsensitiveString和String进行比较,代码如下:

另一个例子: 现在需要继承这个Point,并加上Color属性如下: 这样写违反了对称性(用一个Point与ColorPoint比较如:Point p = new Point(1, 2); ColorPoint cp = new ColorPoint(1, 2, Color.RED);)。改写equals如下: 这样写避免了Point与ColorPoint比较时造成的对称性违反。但是违反了传递性:事实上,在这种情况下无法实现满足这些性质的equals方法。There is no way to extend aninstantiable class and add a value component while preserving the equalscontract。这里的解决方法是:Item 16.Favorcomposition over inheritance.代码如下:在Java类库中,java.sql.Timestampextends java.util.Date and adds a nanoseconds field.The equals implementationfor Timestamp does violate symmetry.将两者同时用在一个Collection中会导致错误。

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 matches the corresponding field of this object.

primitive fields whose type is not float or double : ==

float/double fields:Float.compare/Double.compare(for Float.NaN, -0.0f)

object reference fields : equals

array:Arrays.equals

Some object reference fields may legitimately contain null.To avoid the possibility of a NullPointerException, use this idiom to compare such fields: (field == null ? o.field == null : field.equals(o.field))

5. When you are finished writing your equals method, ask yourself three questions: Is it symmetric? Is it transitive? Is it consistent?

你可能感兴趣的:(Effective Java)