Question

Just for fun, I'm trying to implement a generic Pair class in Java. I'm having trouble with equals:

public class Pair<A, B>
{
    public final A _1;
    public final B _2;

    // ... unnecessary details left out ...

    public boolean equals(Pair<A, B> that)
    {
        return (_1.equals(that._1)) && (_2.equals(that._2));
    }

    @Override
    public boolean equals(Object o)
    {
        return (o instanceof Pair<A, B>) && equals((Pair<A, B>) o);
    }
}

However, o instanceof Pair<A, B> does not seem to work. Why is that?

Using (o instanceof Pair) && equals((Pair<A, B>) o) gives me a warning for the cast. Getting rid of the <A, B> part on the cast still gives me a warning, which I guess also some sense.

Does that mean Java cannot prevent clients from comparing Pairs with different type arguments?

Was it helpful?

Solution

Does that mean Java cannot prevent clients from comparing Pairs with different type arguments?

Yes, but that's the point -- equals should work with any arbitrary object. What you want would look like

@Override
public boolean equals(Object o)
{
    if (o instanceof Pair) {
       Pair<?, ?> pair = (Pair<?, ?>) o;
       return _1.equals(pair._1) && _2.equals(pair._2);
    }
    return false;
}

But this should be fine, as long as A and B have proper implementations of equals that take arbitrary Objects.

OTHER TIPS

You can not use instanceof like you do due to type erasure. You can only check for instanceof Pair.
Also what is up with that _1 and _2? Really?

o instanceof Pair<A, B> 

does not work because generics are not there at runtime, therefore instanceof is not aware of them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top