javagenericsinterfacecomparableraw-types

Implementing Comparable with a generic class


I want to define a class that implements the generic Comparable interface. While in my class I also defined a generic type element T. In order to implement the interface, I delegate the comparison to T. Here is my code:

public class Item<T extends Comparable<T>> implements Comparable<Item> {

    private int s;
    private T t;

    public T getT() {
        return t;
    }

    @Override
    public int compareTo(Item o) {
        return getT().compareTo(o.getT());
    }
}

When I try to compile it, I get the following error information:

Item.java:11: error: method compareTo in interface Comparable<T#2> cannot be applied to given types;
        return getT().compareTo(o.getT());
                     ^
  required: T#1
  found: Comparable
  reason: actual argument Comparable cannot be converted to T#1 by method invocation conversion
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<T#1> declared in class Item
    T#2 extends Object declared in interface Comparable
1 error

Can anybody tell me why and how to fix it?


Solution

  • Item (without any type argument) is a raw type, so:

    1. We could pass any kind of Item to Item.compareTo. For example, this would compile:

      new Item<String>().compareTo(new Item<Integer>())
      
    2. The method o.getT() returns Comparable instead of T, which causes the compilation error.

      In the example under the 1st point, after passing Item<Integer> to Item.compareTo, we would then erroneously pass an Integer to String.compareTo. The compilation error prevents us from writing the code which does that.

    I think you just need to remove the raw types:

    public class Item<T extends Comparable<T>>
    implements Comparable<Item<T>> {
    
        ...
    
        @Override
        public int compareTo(Item<T> o) {
            return getT().compareTo(o.getT());
        }
    }