Подтвердить что ты не робот

Могу ли я преобразовать следующий код для использования дженериков?

Я конвертирую приложение для использования 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) "в качестве члена необработанного типа" java.lang.Comparable "в строке:

return o1.compareTo(o2);
4b9b3361

Ответ 1

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

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

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

Ответ 2

Здесь нечетный случай:

static class A {
    ...
}

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

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

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

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

Ответ 3

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

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

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

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

public static <T extends Comparable<? super T>> void sort(List<T> list) {

Ответ 4

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

Добавляя дженерики, вы не добавите никакой безопасности для кода; любые проблемы безопасности будут возникать в вызове compareTo. Я бы предложил просто подавить предупреждение. Это действительно не предупреждает вас ни о чем полезном.

Ответ 5

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

  /**
   * 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);
    }
  }