1

I want to compare the stats for two people using a custom made equals method that will override the equals method in the Object class. Since the return type of this equals method will be a boolean, I know that I need to pass in the (Object obj) parameter. As I define the new equals method, I was taught that I need to first do a check that the obj class does not match the instance class. Once that is verified, I type-cast the obj class to the instance class, and can carry on with the rest of the code.

However, I do not understand why I need to verify that the obj class does not match the instance class. I thought the two classes are supposed to not match, hence the need for the type-cast.

Can anybody tell me why we need to verify that the obj class does not match the instance class? The code I am working on is written below.

public boolean equals(Object obj) {
    if (obj == null || obj.getClass() != this.getClass())
        return false;
    else {
        Person pp2 = (Person) obj;

        if (this.name.equals(pp2.name) && this.age == pp2.age)
            return true;
        else
            return false;
    }
}

public static void main(String[] args) {
     Person ps1 = new Person("Buddy", 14);
     Person ps2 = new Person("Buddy", 14);

     if (ps1.equals(ps2))
        System.out.println("Same");
}
5
  • There may be two different class which have same variables. Student vs Person, both have name and age, but they are different classes. Commented Oct 8, 2015 at 6:09
  • on a sidenode, using obj instanceof Person will do both, check for class equality and if the obj is not null Commented Oct 8, 2015 at 6:11
  • Since the ps2 is from the Person class, and obj is from the Object class, wouldn't the class match verification always fail as soon as you call ps1.equals.ps2 before you can type-cast anything? That is why I am confused. Commented Oct 8, 2015 at 6:15
  • @OmarN ps2.equals(new Person()) will make obj instance of person. so getClass wil return Person class. Commented Oct 8, 2015 at 6:17
  • Gotcha, understood. Thank you! Commented Oct 8, 2015 at 6:26

3 Answers 3

4

What you suggest to do is that:

public boolean equals(Object obj) {
    Person pp2 = (Person) obj;
    return (this.name.equals(pp2.name) && this.age == pp2.age);
}

This would violate the equals() method contract, which clearly says that the method must return false when the two objects are not considered equal. That would not be the case here: the method would throw a ClassCastException instead (or a NullPointerException if obj is null).

Sign up to request clarification or add additional context in comments.

7 Comments

But since we are passing ps2 through equals when we call (ps1.equals(ps2)), and ps2 belongs to the Person class, doesn't this mean that the class types will not match, since obj is of the Object class? Since they do not match classes, that is why I do not understand why we check for it.
a Person is an Object. Referring to a Person as an object doesn't change its type: it's still a Person, and the actual class returned by obj.getClass() is still Person. That's polymorphism. And it works lile in real life. Although your phone is an iPhone 6S, I can refer to it as "a phone", "an electronic gadget", or "an object", and that doesn't change the fact that it's still a iPhone 6S.
Ok I think I understand. So the verification succeeds because the Object class equals the Person class since Person is a subclass of Object?
Almost. You can refer to the Person instance as an Object because the class Person extends the class Object. That's why you can call equals() with a Person as argument. obj.getClass() returns the class Person because obj is, really, an instance of the class Person. It would return the class Dog if obj was a reference to an instance of Dog. But Dog can also be referred to as an Object, because it also extends Object.
@sedpol have you considered reading the answer. It says that. Explicitely.
|
2

If you do not check for the type of the other obj, then you might get a ClassCastException when someone calls

new Person("Jim",12).equals(new ArrayList())

You don't want that. You want to return false instead of crashing.

Comments

-1

You can use:

if (obj instanceof Person){
}

2 Comments

Using instanceof instead of checking for class identity would violate the contract for equals because it breaks symmetry.
@Drunix: Potentially, yes. But you could match all other subclasses' equals implementations to preserve symmetry. In fact, this is actually done by things like List. They are supposed to be equal, even if the container class is different.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.