Alex headshot

AlBlue’s Blog

Macs, Modularity and More

JavaWorld article on .equals() method in Java

2004 Java Article

JavaWorld has just published my article on object equality, in which I discuss how to implement the equals and 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 Enumeration interface, and called it Iterator for no (good) reason. It's not even that most people need to use Iterator's 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 Enumeration interface, 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 Map interface also defines methods to add/remove/get an iterator along with it. It would not have been that difficult to define interfaces (alal Dictionary to provide abstract data access as well as a slightly more concrete data structure. Now, many developers implement Map just to provide get and set methods, 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.