Addev
Addev

Reputation: 32263

Know if an object is subclass of other in Java

I'm overriding the equals(Object o) method of an Object that is identified by an string:

class User {
@Override
public boolean equals(Object o) {       
    return o != null && o.hashCode() == this.hashCode();
}

@Override
public int hashCode() {
    return id.hashCode();
}
}

But I'd like to check also if o is a subclass of this or vice versa before returning true in the method equals()

for the first case I can use if (o instance of User) but how can I make the check in the other way?

Thanks

Edit: Since I've not explained it correctly I'm going to explain the complete problem:

I have the class

public abstract class UniqueIdentifiedObject<E> {
    private E id;

    protected UniqueIdentifiedObject(E id) {
        super();
        this.id = id;
    }

    public E getId() {
        return id;
    }

    @Override
    public boolean equals(Object o) {
        return o != null && o.hashCode() == this.hashCode();
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

}

and the idea is to inherit this class with an object when it is unique identified by a element: For example if the Users of my app are identified by a integer i'll use:

class User extends UniqueIdentifiedObject<Integer>

and for the Movies

class Movie extends UniqueIdentifiedObject<Integer>

The problem with this implementation of UniqueIdentifiedObject is that if call equals() with the movie with id = 1 and the user with the id=1 it will return true.

How can I solve this?

Upvotes: 0

Views: 819

Answers (2)

DThought
DThought

Reputation: 1314

First: your code will work in most of the cases, but it is good practice to calculate equals() based on equalness, to avoid false-positives.

you can check dynamic types with "Class.isAssignableFrom", so e.g.

   this.getClass().isAssignableFrom(other.getClass())

will tell you, whether other is either the same class, or any subclas of "this". (As this must be an superclass to other)

I don't see the need to do that here, though

you can assure "this" to be a subclass of User, and if you can assure that other is of the same type, it should work out of the box.

so in your case, the method could look like

class User {
@Override
public boolean equals(Object o) {
   if (o==null) {
      return false;
   }
   if (o instanceof User) {
     return (o.id==null && id==null ) || (o.id.equals(id));
   }
}
@Override
public int hashCode() {
    return id.hashCode();
}
}

Upvotes: 0

John B
John B

Reputation: 32969

this.getClass().isAssignableFrom(o.getClass());

Class.isAssignableFrom

From the javadoc:

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.

So the above checks that the class returned by this is a superclass of the class returned be o.

Upvotes: 4

Related Questions