Как установить ограничения на общие типы в Java?

У меня есть общий класс:

public class ListObject<T>
{
    // fields
    protected T _Value = null;
      // ..
}

Теперь я хочу сделать что-то вроде следующего:

ListObject<MyClass> foo = new ListObject<MyClass>();
ListObject<MyClass> foo2 = new ListObject<MyClass>();
foo.compareTo(foo2);

Вопрос:

Как я могу определить метод compareTo() в отношении общего T?

Я думаю, мне нужно как-то реализовать ограничение на общий T, чтобы сказать, что T реализует определенный интерфейс (возможно, Comparable, если он существует).

Может ли кто-нибудь предоставить мне небольшой образец кода?


person citronas    schedule 17.01.2010    source источник


Ответы (4)


Прочтите также обсуждение здесь: Обобщения и сортировка в Java

Короткий ответ, лучшее, что вы можете получить, это:

class ListObject<T extends Comparable<? super T>> {
    ...
}

Но есть также причина просто использовать:

class ListObject<T extends Comparable> {
    ...
}
person nanda    schedule 17.01.2010
comment
Я пока остановлюсь на ListObject‹T extends Comparable›. - person citronas; 17.01.2010
comment
Также проверьте соответствующий поток: stackoverflow.com/questions/2064169/, в котором обсуждается необходимость подстановочного знака формы:‹? супер Т› - person sateesh; 17.01.2010

Это зависит от того, что именно вы хотите, чтобы метод compareTo делал. Простое определение метода compareTo для получения других значений ListObject<T> выполняется следующим образом.

public class ListObject<T> {
  public int compareTo(ListObject<T> other) {
    ...
  }
}

Однако, если вы хотите на самом деле вызывать методы для этого параметра, вам нужно добавить некоторые ограничения, чтобы предоставить больше информации о значении T, например так

class ListObject<T extends Comparable<T>> {
  ...
}
person JaredPar    schedule 17.01.2010

Попробуйте public class ListObject<T extends U>. Только T, реализующие U (или производные от U), будут допустимыми заменами.

person John Feminella    schedule 17.01.2010
comment
Выдает мне ошибку компилятора. Даже с таким простым TestClass: открытый класс ConstraintTest‹T реализует Comparable› { } Ожидается синтаксическая ошибка в токене. Что я упускаю? - person citronas; 17.01.2010
comment
@citronas: На самом деле это extends даже для интерфейсов. Обратите внимание, что если вы используете базовый класс с атрибутом extends, вы фактически можете добавить базовый класс непосредственно к сгенерированному объекту, что является самым большим (и худшим) побочным эффектом расширения generics. - person Esko; 17.01.2010

person    schedule
comment
-1 Проголосовали против, потому что Comparable без параметра типа является необработанным типом, который вам не следует использовать с Java 1.5+ - person helpermethod; 17.01.2010