How to implement equal for generic types?

Suppose I have a generic container type like:

public final class Container<T> {

    public final T t;

    public Container(final T t) {
        this.t = t;
    }
}

      

I want to implement equals to get this through:

final Container<Object> a = new Container<>("Hello");
final Container<String> b = new Container<>("Hello");

assertNotEquals(a, b);

      

Instances of a

and b

must be different because their type parameter is T

different.

However, due to erasure, this is difficult to do. This implementation, for example, is wrong:

@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj != null && obj instanceof Container<?>) {
        final Container<?> other = (Container<?>)obj;
        return Objects.equals(this.t, other.t);
    }
    return false;
}

      

I expect that I will need to store some kind of token for T

.

How to implement equal for generic types?


This doesn't answer the question.

+3


source to share


1 answer


you can modify the Container class a bit and add this field:

public final Class<T> ct;

      

with this and the equation of equality, then



System.out.println(a.equals(b));

      

will return false

because the equals method checks Class<String>

vsClass<Object>

class Container<T> {

    public final T t;
    public final Class<T> ct;

    public Container(final T t, Class<T> ct) {
        this.t = t;
        this.ct = ct;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = (prime * result) + ((ct == null) ? 0 : ct.hashCode());
        result = (prime * result) + ((t == null) ? 0 : t.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Container other = (Container) obj;
        if (ct == null) {
            if (other.ct != null)
                return false;
        } else if (!ct.equals(other.ct))
            return false;
        if (t == null) {
            if (other.t != null)
                return false;
        } else if (!t.equals(other.t))
            return false;
        return true;
    }

}

      

+3


source







All Articles