I read this SO post after I wrote out the title but still decided to go through with the question on bug-proof implementations of equals in Java. This is my normal implementation
@Override
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof CompositePk == false) return false;
if(this == o) return true;
CompositePk that = (CompositePk)o;
return new EqualsBuilder().append(this.id, that.id)
.append(this.bucketId, that.bucketId)
.isEquals();
}
using Apache’s EqualsBuilder to do the mundane stuff. Even easier than this is my Netbean’s automatically generated equals(o) implementation
@Override
public boolean equals(Object obj){
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TemplatesWrapper other = (TemplatesWrapper) obj;
if (this.timeAdded != other.timeAdded && (this.timeAdded == null || !this.timeAdded.equals(other.timeAdded))) {
return false;
}
return true;
}
I take these from 2 diff projects but they both try to accomplish the same thing but using diff approaches. Which style would you rather or are there any flaws you spot?
I would do it this way:
The two lines in the middle are different. One allows for subclasses to be equal (the first one), the other doesn’t. Use whichever one is appropriate.
To give you an example, Java’s
AbstractListclass will probably use the second form, because the exact implementation ofListis irrelevant. what matters is if the members are equal and in the same position.Conversely, a Person class should use the first form (instanceof) because if there is a Student subclass and you call
Person.equals(Student)it may return true without checking the extra fields in Student whereas Student.equals(Person) will probably returnfalse. Ifequals()isn’t commutative, you’re asking for trouble.I tend to use
equals()methods generated by my IDE (IntelliJ IDEA) rather than creating an unnecessary dependency to some Apache library for little gain.