I am redefining a method equals()in a Java class and have discovered a riddle that I cannot explain.
The equals()following is specified in the standard contract :
- This is reflective: for any reference value x, x.equals (x) should return true.
- It is symmetrical: for any reference values x and y, x.equals (y) should return true if and only if y.equals (x) returns true.
- This is transitive: for any reference values x, y, and z, if x.equals (y) returns true, and y.equals (z) returns true, then x.equals (z) should return true.
- This is consistent: for any reference values x and y, multiple calls to x.equals (y) successively return true or successively return false if no information used in equal comparisons with the object is changed.
- For any non-zero reference x, x.equals (NULL) should return false.
Therefore, the standard method equals()will be constructed as follows:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof MyClassName)) return false;
MyClassName that = (MyClassName) other;
return this.myMemberVariable.equals(that.name);
}
Given the class Fooand the class Bar extends Foo, as with a member variable String baz, the standard equals()method inside Foolooks like this:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof Foo)) return false;
Foo that = (Foo) other;
return this.baz.equals(that.name);
}
While the standard equals()method inside Barlooks like this:
public boolean equals(Object other) {
if (null == other) return false;
if (this == other) return true;
if (!(other instanceof Bar)) return false;
Barthat = (Bar) other;
return this.baz.equals(that.name);
}
Foo foo = new Foo("Test"); Bar bar = new Bar("Test");, foo.equals(bar), true. bar.equals(foo) equals(), , equals() of Bar, (!(other instanceof Bar)) true, Bar equal() return false > , , true, ( String baz ) , if x.equals(y), y.equals(x) true.
getClass() vs instanceof equals() .
. , equals(), Java ?