commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Blewitt <>
Subject Re: JavaDoc of org.apache.commons.lang.builder.EqualsBuilder
Date Sat, 19 Oct 2002 00:32:31 GMT
> I think I agree about the instanceof check in the code. It probably 
> should
> be class equality.
> I am unclear as to what you find exactly wrong with Josh Bloch's book. 
> I
> have never heard of it being ridiculed, but then maybe I'm not in the 
> right
> circles :-)

His principle of 'least surprise' is a good one, but he has chosen the 
surprise himself and implemented equals to break the contract. Consider:

public class TwoD {
   private int x,y;
   public TwoD(int x, int y) { this.x = x; this.y = y; }
public class ThreeD extends TwoD {
   public int z;
   public ThreeD(int x, int y, int z) { super(x,y); this.z = z; }

if 'equals' is implemented in TwoD as:

public boolean equals(Object o) {
   if (o instanceof TwoD) {
     TwoD other = (TwoD)o;
     return other.x = x && other.y == y;
   } else {
    return false;

then we have

TwoD zero = new TwoD(0,0);
ThreeD nonZero = new ThreeD(0,0,5);
zero.equals(nonZero) == true;
nonZero.equals(zero) == false;

Not only does this break reflexivity, it may also break transitivity. 
Joshua Bloch's argument about comparing objects using a partial set was 
completely ignorant of comparison of type as well; clearly, if a TwoD 
point in space was extended to ThreeD, then it would (probably) be 
0,0,0, which would not then be the same as 0,0,5 (or indeed, 
0,0,Math.random()*1000); which the implementation using instanceof 
gives you.

This is why the implementation in his book has been ridiculed :-)

Replacing the instanceof line with

if (other == null || this.getClass() != other.getClass()) { return 
false; }

is the only safe way to provide instance comparisons.

[NB for super- and sub-classes, this test only needs to be done at the 
root class that defines the equals method. Other subclasses can then 
safely assume if super.equals(other) returns true, then a direct cast 
is compatible.]


To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message