I never said Josh changed his views. I said version 1.0 contained a bug. Which that second snippet clearly shows: Using instanceof like that, _unless_ some documentation explicitly states that cross-type equality is intended (and thus also locks down any subclasses from adding equality-relevant state), cannot result in a transitive equals method.
On Oct 17, 11:48 am, grydholt <grydh...@gmail.com> wrote: > On Oct 17, 8:06 am, Reinier Zwitserloot <reini...@gmail.com> wrote: > > > > > > > > > > > Equality in java is a lot more problematic than you might at first > > glance think. Josh Bloch, when he wrote effective java, proposed the > > following template for writing equals methods. Let's assume we have a > > simple point class: > > > public boolean equals(Object o) { > > if (o == null) return false; > > if (o == this) return true; > > if (!(o instanceof Point)) return false; > > if (((Point)o).x != this.x) return false; > > if (((Point)o).y != this.y) return false; > > return true; > > > } > > > Simple enough. But wrong. In the second edition, the instanceof check > > was revised to this: > > > if (o.getClass() != this.getClass()) return false; > > We must have two different copies of the second edition. In mine it > says: > > <quote> > // Broken - violates Liskov substitution principle (page 40) > @Override public boolean equals(Object o) { > if (o == null || o.getClass() != getClass()) > return false; > Point p = (Point) o; > return p.x == x && p.y == y;} > > </quote> > > And later: > > <quote> > Putting it all together, here’s a recipe for a high-quality equals > method: > > [snip] > 2. > Use the instanceof operator to check if the argument has the correct > type. If not, return false. Typically, the correct type is the class > in which the method occurs. Occasionally, it is some interface > implemented by this class. Use an interface if the class implements an > interface that refines the equals contract to permit comparisons > across classes that implement the interface. Collection interfaces > such as Set, List, Map, and Map.Entry have this property. > > 3. > Cast the argument to the correct type. Because this cast was preceded > by an instanceof test, it is guaranteed to succeed. > > [snip] > 5. > When you are finished writing your equals method, ask yourself three > questions: Is it symmetric? Is it transitive? Is it consistent? And > don’t just ask yourself; write unit tests to check that these > properties hold! If they don’t, figure out why not, and modify the > equals method accordingly. Of course your equals method also has to > satisfy the other two properties (reflexivity and “non-nullity”), but > these two usually take care of themselves. > </quote> > > So Josh Bloch does not change his views from the first to the second > edition, but extends the treatment on the subject because a lot of > people did not understand the implications of the use of 'instanceof' > in the equals method. > > Kind regards, > Jacob Grydholt -- You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to javapo...@googlegroups.com. To unsubscribe from this group, send email to javaposse+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.