Могу ли я преобразовать следующий код, чтобы использовать дженерики? - PullRequest
18 голосов
/ 12 сентября 2008

Я конвертирую приложение для использования Java 1.5 и нашел следующий метод:

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2
   */
  protected static int nullCompare(Comparable o1, Comparable o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }

В идеале я хотел бы, чтобы метод брал два сопоставимых объекта одного и того же типа, возможно ли преобразовать это и как?

Я думал, что следующее поможет:

protected static <T extends Comparable> int nullCompare(T o1, T o2) {

, но ему не удалось избавиться от предупреждения в IntelliJ "Не проверенный вызов 'compareTo (T)' как члена типа raw" java.lang.Comparable "" в строке:

return o1.compareTo(o2);

Ответы [ 5 ]

21 голосов
/ 12 сентября 2008

Измените его на:

protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) {

Вам это нужно, потому что Comparable сам по себе является универсальным типом.

5 голосов
/ 17 сентября 2008

Вот странный случай:

static class A {
    ...
}

static class B extends A implements Comparable<A> {
    public int compareTo(A o) {
        return ...;
    }
}

К счастью, подобный приведенному выше код является редким, но nullCompare () не будет поддерживать сравнение B, если не указано, что Comparable может применяться к T или любому его суперклассу :

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

Несмотря на то, что большинство людей никогда не получат выгоду от вышеуказанной настройки, она может пригодиться при разработке API для экспортируемых библиотек.

2 голосов
/ 23 октября 2008

Невозможно изменить, поэтому я должен опубликовать свой ответ.

Вам необходимо объявить параметр вложенного типа, поскольку Comparable является универсальным.

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

Обратите внимание, что Comparable <? супер T> , что делает более гибким. Вы увидите то же определение метода на Collections.sort

public static <T extends Comparable<? super T>> void sort(List<T> list) {
0 голосов
/ 02 мая 2009

Чтобы сделать его еще более общим, вы можете даже позволить ему работать для двух разных типов. = Р * * тысяча одна

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1&lt;o2, 0 if o1==o2, 1 if o1&gt;o2
   */
  protected static <T> int nullCompare(Comparable<? super T> o1, T o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }
0 голосов
/ 22 сентября 2008

Я не уверен, что обобщение этого метода имеет смысл. В настоящее время метод работает на любом типе Comparable; если вы генерируете его, вам придется реализовывать его (с точно таким же кодом) несколько раз. Иногда можно сравнить два объекта, которые не имеют общего предка, и любая универсальная версия не допустит этого.

Добавляя генерики, вы не добавляете никакой безопасности к коду; любые проблемы безопасности будут возникать при обращении к сравнению. То, что я хотел бы предложить, это просто подавить предупреждение. На самом деле он не предупреждает вас о чем-либо полезном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...