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

StackOverflow https://stackoverflow.com/questions/59107

  •  09-06-2019
  •  | 
  •  

Вопрос

Я конвертирую приложение для использования 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);
    }
  }

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

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

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

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

return o1.compareTo(o2);
Это было полезно?

Решение

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

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

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

Другие советы

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

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 для экспортируемых библиотек.

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

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

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

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

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

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

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

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

  /**
   * 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);
    }
  }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top