Java “unchecked call to compareTo(T) 作为原始类型 java.lang.Comparable 的成员”

2022-09-01 20:33:59

我正在尝试在Java中实现一个排序列表作为一个简单的练习。为了使它成为泛型,我有一个,所以我可以将其与实现Compable接口的任何类一起使用。add(Comparable obj)

但是,当我在代码中的任何位置使用时,我从编译器(带有选项)获得。代码工作得很好,但我不知道如何摆脱那个烦人的消息。obj.compareTo(...)"unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable"-Xlint:unchecked

任何提示?


答案 1

从本质上讲,此警告表示对象不能与任意对象进行比较。 是一个通用接口,其中 type 参数指定可以与此对象进行比较的对象的类型。ComparableComparable<T>T

因此,为了正确使用,您需要使排序列表成为通用列表,以表达列表存储可以相互比较的对象的约束,如下所示:Comparable<T>

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

答案 2

使用像方法参数这样的接口不会使类泛型,声明和使用泛型类型参数是使其泛型的方式。Comparable

快速 n 肮脏的答案:您收到警告是因为您正在使用 ,这是一个泛型接口,作为原始类型,而不是为其提供特定的类型参数,如 .ComparableComparable<String>

要解决此问题,请通过指定类型参数来使泛型:add()

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

但是,此快速修复程序无法解决您的类不安全的一般问题。毕竟,列表中的所有对象不应该都是同一类型的吗?此方法允许您在同一列表中仍然使用不同的类型。当您尝试比较异构类型时会发生什么情况(如何将实例与实例或 String 实例进行比较)?您可以依靠类的用户来执行正确的操作,并确保他们只将 1 种内容粘贴到列表中,但泛型类将允许编译器强制执行此规则。addcompareToObjectNumber

更好的方法:正确的解决方法是,排序列表类总体上应该是泛型的,就像 中的其他集合类一样。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; } 
}

推荐