views:

60

answers:

3

I'm trying to understand the equals() method better. All examples I've seen do something like:

public class City
{
    public boolean equals(Object other)
    {
        if (other instanceof City && other.getId().equals(this.id))
        {
            return true;
        }

        // ...
    }
}

Must the method take on Object and not a City?

E.g. is this below not allowed?

public class City
{
    public boolean equals(City other)
    {
        if (other == null)
        {
            return false;
        }

        return this.id.equals(other.getId());
    }
}

Thanks.

+6  A: 

Yes, it must be an Object. Else you're not overriding the real Object#equals(), but rather overloading it.

If you're only overloading it, then it won't be used by the standard API's like Collection API, etc.

Related questions:

BalusC
And use `@Override` to make sure you haven't made a mistake.
Tom Hawtin - tackline
Is that a problem? What effect does it have?
sje397
it has the effect that the equals method you think you wrote won't be used
matt b
A: 

Don't take anything else than an Object if you want to override equals()!

Writing a specialized equals() method is a common error but tends to violate the equals() contract.

PartlyCloudy
You can however do both, overloading it with a special `equals( City )` method, that is specialized in checking two cities, and then overriding the original `equals( Object )` method in which you will call `equals( City )` if the passed object is a City and do something else otherwise (like return false always).
poke
@poke - +1 for great point! I find myself doing this quite often, on some rare occasions it has had a positive performance impact.
mikera
Of course you two are right. What I meant is that this often leads to error prone code. As long as you know what you are doing and use the override annotation properly, there is no big deal.
PartlyCloudy
+1  A: 

you can have both: (see poke's comment above)

public class City
{
    public boolean equals(Object other)
    {
        return (other instanceof City) && equals((City)other) ;
    }
    public boolean equals(City other)
    {
        return other!=null && this.id.equals(other.getId());
    }
}
irreputable