JavaWorld has just published my article on object equality, in which I discuss how to implement the
hashCode methods in Java. I also go at lengths to point out one of Bloch's Blunders; specifically, that
instanceof should never be used to implement an equality method because that it does not preserve transitivity.
Unfortunately, some Java developers are still under the misconception that because Effective Java uses the antiquated
instanceof approach, that this must be superior. However, even when interviewed on artima.com, he couldn't really come up with a good reason why he didn't use the correct approach in the first place. Reading between the lines, it's obvious that he hadn't come across that method and suffered from the 'Not Invented Here' syndrome, and as a result, hasn't updated the Effective Java book to reflect the correct impementation.
It should be noted that Bloch is no stranger to making bad calls; he was one of the foremost designers in the Collections hierarchy, and made a couple of bad calls:
- He decided that the method
getSize(), although being part of the JavaBeans coding conventions, was too much to type for developers and so they should have
size()methods instead. This has caused no end of problems in JSP-like languages, to the extent where special workarounds are needed when presenting the size of a collection in dynamic JavaBean aware systems.
- He re-created the
Enumerationinterface, and called it
Iteratorfor no (good) reason. It's not even that most people need to use
remove()method, and it was only a marginal optimisation in general. (You could still use the opaque type instead of the iterator to remove the element in-place.) What he should have done would be to create a subtype of the
Enumerationinterface, and added the remove method to that if it were required.
- He designed the interfaces to be tightly defined in with the data structures. For example, an interface that allowed you to get/set values dymanically would have had major uses in Java; yet the
Mapinterface also defines methods to add/remove/get an iterator along with it. It would not have been that difficult to define interfaces (alal
Dictionaryto provide abstract data access as well as a slightly more concrete data structure. Now, many developers implement
Mapjust to provide
setmethods, either leaving the others unimplemented, or throwing an exception type.
Of course. Bloch can't be held to blame for all the bad design in Java (he didn't play a part in the fiasco known as the
Date class, which indexes months from 0..11 and counts years since 1900 -- and then goes at anal length to discuss the differences in leap seconds between GMT and UTC), but his design errors and NIH syndrome have affected everyone from Java 1.2 onwards.