Translator: You might think Java is very simple, the equals implementation of object will be very simple, but the fact is not what you think, after reading this article patiently, you will find that you know so little about Java. If this article is a Java Programmer's entry test, then I don't know how many people will fall into such a trap.
Summary
This article describes the technique of overloading the Equals method, which can guarantee the correctness of equal semantics even if the subclasses of the present class add fields.
In the 8th item of the effective Java, Josh Bloch describes the difficulty of deriving the equal correctness semantics of derived classes when inheriting classes are fundamental to the equivalence relationship in object-oriented languages. Bloch wrote this:
Unless you forget the benefits of object-oriented abstraction, you cannot guarantee that the semantics of equal are still correct when you inherit a new class or add a value component to a class.
The 28th chapter in "Programming in Scala" shows a method that allows the semantics of equal to be guaranteed even if new classes are inherited and new value components are added. Although this technique is used in the Scala environment in this book, this technique can also be applied to Java-defined classes. The description in this article comes from a textual description in the programming in Scala, but the code is translated from Scala to Java
Common equivalent Method traps
The Java.lang.Object class defines the method of equals, and its subclasses can override it by overloading it. Unfortunately, it is very difficult to write the correct equals method in an object-oriented way. In fact, after studying a lot of Java code, 2007 paper's author came to the following conclusion:
Almost all of the Equals method implementations are wrong!
The problem is that equivalence is associated with many other things. For example, one of the error equivalence methods of type C may mean that you cannot put the object of this type C into the container in a trustworthy way. For example, you have two elements elem1 and elem2 they are all objects of type C, and they are equal, that is, Elem1.equals (elm2) returns ture. However, as long as the Equals method is the wrong implementation, you may see some of the following behaviors:
Set hashSet<C> = new java.util.HashSet<C>();
hashSet.add(elem1);
hashSet.contains(elem2); // returns false!
When equals overloads, there are 4 common pitfalls that cause the equals behavior to be inconsistent:
The Equals method signature (signature) that defines the error defining equals with the wrong signature.
Overloaded a method that equals but does not overload hashcode at the same time. Changing equals without also changing hashcode.
Establishes the equals definition on the changing word field. Defining equals in terms of mutable fields.
equals error definitions that do not satisfy the equivalence relation failing to define equals as a equivalence relation.
In the remainder of the chapters we will discuss the 4 traps in turn.
Trap 1: Define error Equals method signature (signature)
Consider adding an equivalence method for the following simple class point:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
// ...
}