Poornima Prakash
Poornima Prakash

Reputation: 330

Overriding equals() method in a generic class

I want to override equals() method in this class. I follow the usual rules while overriding the equals() method but and I typecast the Object into my class type

but in my equals() method, I want to return true only if the objects are of the same generic type.

How can I check the run time type of the instance in my equals() method?

Here is my code:

public class GenericsRunTimeType<T> {

private T foo;
public GenericsRunTimeType(T foo){
    this.foo = foo;

}

@Override
public boolean equals(Object obj){
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;

    // Before doing this I want to test if obj and this are of the same generic type
    GenericsRunTimeType other = (GenericsRunTimeType) obj;
    if(other.equals(obj))
        return true;
    else
        return false;
}

}

Upvotes: 2

Views: 4875

Answers (3)

Adrian Shum
Adrian Shum

Reputation: 40076

I am giving another direction: Do you really need to check the equality of the TYPE PARAMETER?

Given foo in your example should be part in the equality, normally the equals() method should looks like

public boolean equals(Object obj){
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (!obj instanceof GenericsRunTimeType)
        return false;

    GenericsRunTimeType other = (GenericsRunTimeType) obj;

    return (this.foo.equals(obj.foo))  // !Here
    // can be better wrote as foo==obj.foo || (foo != null && foo.equals(obj.foo))
    // I wrote in a simpler form just to give you the idea

}

Whether the two foo is of the same type, it is normally the responsibility of the equals() of foo to deal with. If you don't care whether the two foo is equals, then why should you care for whether both foos are of the same type?

Of course there are other choices like what suggested by other answer, where you get the type from foo and compare them or pass in another Class object. However I think probably not necessary in most case.

Upvotes: 2

Rohit Jain
Rohit Jain

Reputation: 213411

One option is to use Reflection, but I would consider it as my last resort.

Another option, which I would prefer here, is to pass Class<T> parameter in constructor, and store it in a field:

private T foo;
private Class<T> clazz;
public GenericsRunTimeType(T foo, Class<T> clazz){
    this.foo = foo;
    this.clazz = clazz;
}

And then in equals method, do the comparison like so:

if (this.clazz == ((GenericsRunTimeType)obj).clazz) {
    System.out.println("Same type");
}

Upvotes: 5

AlexR
AlexR

Reputation: 115408

In your case you can just check:

foo.getClass().equals(other.foo.getClass())

This is because you already have a member of class T in your class. However in common case when you do not have such member take a look on answer done by @Rohit Jain. (+1)

Upvotes: 7

Related Questions