Mousa
Mousa

Reputation: 2290

What's a suitable implementation of equals() for a class with no fields?

Let's say I have a class with no fields, but a few methods. For example a class which only implements an interface:

public class SomeClass implements SomeInterface
{
    @Override
    public void someMethod(int param) {...}

    @Override
    public int getSomeValue(OtherClass param) {return ...;}
}

Now I want to override equals() for this. Can I always return true, by arguing that "since the objects don't have any state, they are always equal"?

An implementation like this:

@Override
public boolean equals(Object other)
{
    if (null == other || !(other instanceof SomeClass))
        return false;
    return true;
}


Edit: Since some people asked about the intention behind this, I'm going to elaborate more on the context in which this question arose:

This class is an event-listener. I instantiate and pass it as a listener to an async request, along with some other data, encapsulated in an Object named Config.

In other words, I have a class named Config which is composed of SomeClass and some other data.

public class Config
{
    SomeClass someClass;
    int otherData;
    //...

    @Override
    public boolean equals(Object other) {/*???*/}
}

Actually I wanted to implement equals for this Config class (Because I want to prevent repeated requests). But since one part of the Config is this instance of SomeClass I was wondering what to do with that.


Side question: If the SomeClass is a nested class and have implicit reference for its enclosing class, what to do then? (In my context, it is.)

Upvotes: 4

Views: 1926

Answers (2)

Mureinik
Mureinik

Reputation: 311798

Just returning true is a bad implementation, as it will mean that any instance of your class is equal to any other object, which is probably not what you intended. Moreover, it will break equals' general contract of commutativity, as mySomeClass.equals("Mousa") will return true while "Mousa".equals(mySomeClass) will return false.

As SomeClass has no state, implementing its equals method is a matter of taste. Having any two SomeClass instances be equal to each other is a reasonable choice, although the implementation you suggested can be improved. As other instanceof SomeClass will return false if other is null, the method could just be rewritten as

@Override
public boolean equals(Object other) {
    return other instanceof SomeClass;
}

Also, you should note that in order to maintain the general contract of two equal objects having the same hashCode(), you should override that method too. E.g.:

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

On the other hand, it's also perfectly reasonable to decide that since SomeClass has no state, the only way two objects can be equal to each other is if they both point to the same instance (i.e., the behavior of the == operator). This approach is taken by another famous stateless class you may know from the JDK - java.lang.Object.

Upvotes: 8

glglgl
glglgl

Reputation: 91109

That is a semantical question: what does it mean to have two objects of this class? (Might it even be useful to implement it as a singleton?)

If they can be used interchangeably, they can indeed be considered equal. (Don't forget to override hashCode() then.) But as well, you can keep the original definition which comes from Object.

Upvotes: 4

Related Questions