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

Java "непроверенный вызов compareTo (T) как член исходного типа java.lang.Comparable"

Я пытаюсь реализовать отсортированный список как простое упражнение в Java. Чтобы сделать его общим, у меня есть add(Comparable obj), поэтому я могу использовать его с любым классом, который реализует интерфейс Comparable.

Но когда я использую obj.compareTo(...) в любом месте кода, я получаю "unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable" из компилятора (с опцией -Xlint:unchecked). Код работает нормально, но я не могу понять, как избавиться от этого досадного сообщения.

Любые подсказки?

4b9b3361

Ответ 1

В сущности, это предупреждение говорит о том, что объект Comparable нельзя сравнивать с произвольными объектами. Comparable<T> - это общий интерфейс, где параметр типа T указывает тип объекта, с которым этот объект можно сравнить.

Итак, чтобы правильно использовать Comparable<T>, вам нужно сделать свой отсортированный список общим, чтобы выразить ограничение, что ваш список хранит объекты, которые можно сравнить друг с другом, примерно так:

public class SortedList<T extends Comparable<? super T>> {
    public void add(T obj) { ... }
    ...
}

Ответ 2

Использование интерфейса типа Comparable в качестве параметра метода не делает ваш класс общим, объявляющим и использующим параметры типового типа, как вы делаете его общим.

Быстрый n-грязный ответ:. Вы получаете предупреждение, потому что используете Comparable, который является общим интерфейсом, как необработанный тип, вместо того, чтобы давать ему конкретные аргументы типа, как Comparable<String>.

Чтобы исправить это, создайте add() generic, указав параметры типа:

<T extends Comparable<? super T>> add(T obj) { ... }

Но это быстрое решение не устранит общую проблему, из-за которой ваш класс небезопасен. В конце концов, должны ли все объекты в вашем списке одного типа? Этот метод add позволяет вам использовать разные типы в одном списке. Что происходит, когда вы пытаетесь сравнить гетерогенные типы (как вы compareTo экземпляр Object для экземпляра Number или для экземпляра String)? Вы можете зависеть от пользователя класса, чтобы он поступал правильно, и убедиться, что они только придерживаются одного вида вещей в вашем списке, но общий класс позволит компилятору обеспечить соблюдение этого правила.

Лучший подход: Правильное исправление заключается в том, что ваш отсортированный класс списка должен быть, вероятно, общим, как и другие классы коллекции в java.util.

Вам, вероятно, понравится что-то вроде:

public class SortedList<T extends Comparable<? super T>>
implements Iterable<T> {
    ...
    public void add(T item) { ... }
    public Iterator<T> iterator() { ... }
    ...
}

Обратите внимание, что когда класс является общим, метод add использует параметр формального типа классов вместо объявления его собственного формального параметра типа.

В Интернете должно быть много учебников о том, как создать общий класс, но здесь приведен краткий пример:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#FAQ002

class Pair<X,Y>  {  
  private X first; 
  private Y second;
  public Pair(X a1, Y a2) { 
    first  = a1; 
    second = a2; 
  } 
  public X getFirst()  { return first; } 
  public Y getSecond() { return second; } 
  public void setFirst(X arg)  { first = arg; } 
  public void setSecond(Y arg) { second = arg; } 
}

Ответ 3

Вам нужно "проверить" или определить объект Comparable следующим образом:

add(Comparable<Object> obj)