Реализация Сопоставимый с общим классом

Я хочу определить класс, реализующий общий интерфейс Comparable. В то время как в моем классе я также определил элемент типового типа T. Чтобы реализовать интерфейс, я делегирую сравнение T. Вот мой код:

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());
    }
}

Когда я пытаюсь скомпилировать его, я получаю следующую информацию об ошибке:

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

Может ли кто-нибудь сказать мне, почему и как его исправить?

Ответ 1

В основном компилятор не может доказать, что общий тип o является тем же самым T, что и тип this.

Например, я мог бы сделать следующее:

new Item<String>().compareTo(new Item<Integer>());

Это явно неправильно и является сценарием, который предотвращает компилятор. Я думаю, вам просто нужно удалить необработанные типы:

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

    ...

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

Ответ 2

Вы используете необработанные типы в определении класса (Item<T> является общим, но вы опускаете параметр типа <T>), измените его на:

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

(Обратите внимание на последний <T>)

Затем должен быть также изменен метод compareTo:

public int compareTo(Item<T> o) { // again, use generics
    return getT().compareTo(o.getT());
}

Ответ 3

Думаю, это имеет смысл. Я собрал и протестировал следующее:

class Item<E extends Comparable<E>> implements Comparable<E> {

 private int s;
 private E t;

 public E getE() {
     return t;
 }

 @Override
 public int compareTo(E e) {
     return getE().compareTo(e);
 }

 public int compareTo(Item<E> other)
    {
        return getE().compareTo(other.getE());
    }

 }

Обратите внимание, что теперь вам нужно иметь два метода compareTo.