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.

Reply via email to