-
Book Overview & Buying
-
Table Of Contents
Java Coding Problems - Second Edition
By :
It is not mandatory to rely on instanceof to implement the equals() method, but it is a convenient approach to write something as follows:
public class MyPoint {
private final int x;
private final int y;
private final int z;
public MyPoint(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof MyPoint)) {
return false;
}
final MyPoint other = (MyPoint) obj;
return (this.x == other.x && this.y == other.y
&& this.z == other.z);
}
}
If you are a fan of the previous approach for implementing equals(), then you’ll love rewriting it via a type pattern for instanceof. Check out the following snippet:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
return obj instanceof MyPoint other
&& this.x == other.x && this.y == other.y
&& this.z == other.z;
}
If MyPoint is generic (MyPoint<E>) then simply use a wildcard as follows (more details are available in the next problem):
return obj instanceof MyPoint<?> other
&& this.x == other.x && this.y == other.y
&& this.z == other.z;
Cool, right?! However, pay attention that using instanceof to express the equals() contract imposes the usage of a final class of final equals(). Otherwise, if subclasses are allowed to override equals(), then instanceof may cause transitivity/symmetry bugs. A good approach is to pass equals() through a dedicated verifier such as equals verifier (https://github.com/jqno/equalsverifier), which is capable of checking the validity of the equals() and hashCode() contracts.