Java"unchecked调用compareTo(T)作为原始类型java.lang.Comparable的成员"

3mp*_*pty 23 java generics unchecked 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选项)获得.代码工作正常,但我无法弄清楚如何摆脱这个恼人的消息.

任何提示?

axt*_*avt 30

从本质上讲,这个警告说Comparable对象无法与任意对象进行比较.Comparable<T>是一个通用接口,其中type参数T指定可以与此对象进行比较的对象的类型.

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

public class SortedList<T extends Comparable<? super T>> {
    public void add(T obj) { ... }
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 应该是`T扩展可比较<?超级T>`. (5认同)

Ber*_*t F 9

使用类似Comparable方法参数的接口不会使您的类具有通用性,声明和使用泛型类型参数是如何使其通用的.

快速回答:您正在接收警告,因为您使用的Comparable是通用接口,作为原始类型,而不是给它一个特定的类型参数,例如Comparable<String>.

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

<T extends Comparable<? super T>> add(T obj) { ... }
Run Code Online (Sandbox Code Playgroud)

但是这个快速修复程序无法解决您的课程不安全的一般问题.毕竟,列表中的所有对象不应该是同一类型的吗?此add方法允许您将不同的类型放入同一列表中.当您尝试比较异类类型(你怎么会发生什么compareTo一个Object实例的Number实例,或者一个字符串实例)?您可以依赖类的用户来做正确的事情,并确保他们只在您的列表中添加一种东西,但是泛型类将让编译器强制执行此规则.

更好的方法:正确的解决方案是你的排序列表类应该是通用的,就像其他集合类一样java.util.

你可能会喜欢这样的东西:

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

请注意,当类是通用的时,该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; } 
}
Run Code Online (Sandbox Code Playgroud)