Effective Java 的笔记,代码、英语原文为主,批注、翻译为辅。

Item 10: Obey the general contract when overriding equals

覆盖 equals 方法时请遵守通用约定

Not to override the equals method

1. Each instance of the class is inherently unique.

This is true for classes such as Thread that represent active entities rather than values. The equals implementation provided by Object has exactly the right behavior for these classes.

2. There is no need for the class to provide a “logical equality” test.

For example, java.util.regex.Pattern could have overridden equals to check whether two Pattern instances represented exactly the same regular expression, but the designers didn’t think that clients would need or want this functionality. Under these circumstances, the equals implementation inherited from Object is ideal.

3. A superclass has already overridden equals, and the superclass behavior is appropriate for this class.

For example, most Set implementations inherit their equals implementation from AbstractSet, List implementations from AbstractList, and Map implementations from AbstractMap.

4. The class is private or package-private, and you are certain that its equals method will never be invoked.

If you are extremely risk-averse, you can override the equals method to ensure that it isn’t invoked accidentally:

1
2
3
4
@Override
public boolean equals(Object o) {
    throw new AssertionError(); // Method is never called
}

5. a class that uses instance control to ensure that at most one object exists with each value.

Enum types fall into this category. For these classes, logical equality is the same as object identity, so Object’s equals method functions as a logical equals method.

when is it appropriate to override 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. A programmer who compares references to value objects using the equals method expects to find out whether they are logically equivalent, not whether they refer to the same object. Not only is overriding the equals method necessary to satisfy programmer expectations, it enables instances to serve as map keys or set elements with predictable, desirable behavior.