||Don't Let Hibernate Steal Your Identity|
|Subject:||Instanceof in equals()|
I liked the article as it goes straight into the direction of my own crusade -- people just don't think about object identity enough.
One complaint, though: you should never use instanceof in an implementation of equals(). That will nearly always break symmetry of the equals() relation if a subtype is introduced, since you will find situations where sub.equals(super) is false despite super.equals(sub) being true. The exception where you don't get that is when the relevant fields can not be the same in a subtype and a supertype instance, which seems actually intended in your example -- but you never really know that someone doesn't find a way to subtype your class by introducing a new persistance layer or some other indirection.
Sometimes people claim that not using instanceof would break Liskov's Substitution Principle. That necessarily means they haven't read the relevant paper(s) since Liskov and Wing actually discuss the topic of equality themselves and propose to introduce multiple equality functions. In addition breaking the specification of the equals() method on Object is exactly the type of change that breaks the LSP -- symmetry of the method is trivially provable from the specification, and that is what the LSP is about: Liskov and Wing do not consider extensional arguments at all.
Reference for that last bit: http://citeseer.ist.psu.edu/liskov94behavioral.html
It's just another part of that crusade of mine :-)