Question

I've bumped into an unexpected problem with equals() and hashcode().

Eclipse refused to generate them properly, because Class does not override them. Oh uh.

So I had to compare them by .getName() result, but it is ugly.

private Class<T> clientClass;

@Override
public int hashCode()
{
    final int prime = 31;
    int result = 1;
    result = prime * result + clientClass.getName().hashCode();
    return result;
}


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

    MessageChannel<?, ?> other = (MessageChannel<?, ?>) obj;

    if (!clientClass.getName().equals(other.clientClass.getName())) return false;

    return true;
}

Note that T is a parameter.

How to do this correctly?

Était-ce utile?

La solution

You do not need to do something special to deal equals and hashcode for Class. The current behaviour (inherited from Object) is semantically correct. (If Eclipse is warning you otherwise, ignore it. The warnings are incorrect.)

Isn't it possible that I get two different instances of Class representing the same class? Object just uses == on them afaik. Perhaps with two classloaders or whatever, I'm not that familiar with this reflection magic.

Yes it is possible.

But in that case, they are in fact different classes from the perspective of the Java type system. (See JLS 4.3.4 for details.) And hence, you should be treating them as not equal.

Autres conseils

I would suggest that you do following

@Override
public boolean equals(Object that) {
  return EqualsBuilder.reflectionEquals(that, this);
}

@Override
public int hashCode() {
  return HashCodeBuilder.reflectionHashCode(this);
}

You can read more about this nice builder on http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/builder/package-summary.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top