Java "непроверенный вызов CompareTo (T) в качестве члена необработанного типа java.lang.Comparable" - PullRequest
20 голосов
/ 28 января 2011

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

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

Есть какие-нибудь подсказки?

Ответы [ 3 ]

28 голосов
/ 28 января 2011

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

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

public class SortedList<T extends Comparable<? super T>> {
    public void add(T obj) { ... }
    ...
}
9 голосов
/ 28 января 2011

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

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

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

<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; } 
}
1 голос
/ 28 января 2011

Вам необходимо «проверить» или определить сопоставимый объект следующим образом:

add(Comparable<Object> obj)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...