Search code examples
javagenericsbounded-types

Generics cannot find symbol


I have a class defined as follows:

static class ParallelMergeSort<T extends Comparable<Pair>> extends RecursiveAction

Where Pair is a class defined above with a method getSecond().

In the merge sort class, I have a method defined as:

  private boolean isLess(T a, T b) {
  if (a instanceof Pair<?,?>) return a.getSecond().compareTo(b.getSecond()) < 0;
  return a.compareTo(b) < 0;
  }

Even though I am checking that T will be an instance of Pair the compiler still comes up with the error cannot find symbol:

return a.getSecond().compareTo(b.getSecond()) < 0;
                                ^

What should I change to alleviate this issue?


Solution

  • When you do the check:

    if (a instanceof Pair)
    

    then you should cast a and b to Pair and then do the comparison:

    if (a instanceof Pair && b instanceof Pair) {
        Pair<?, ?> cast_a = (Pair) a;
        Pair<?, ?> cast_b = (Pair) b;
        return cast_a.getSecond().compareTo(cast_b.getSecond()) < 0;
    }
    

    Currently, the compiler fails to compile, because T could be potentially another sub-type of Comparable<Pair>, and since the compiler doesn't have any evidence that T will be exactly Pair then it disallows compilation.

    Few notes on your code:

    • the right operand of the instanceof operator should be just raw. Being generic (as Pair<?, ?>) doesn't make any sense, because this check will be done at Runtime, when the generic information will be erased.
    • I'm not sure if you design is good, so you should re-consider it, at the least. Having to use instanceof is a sign for bad design.