【问题标题】:Java "unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable"Java“作为原始类型 java.lang.Comparable 的成员对 compareTo(T) 的未经检查的调用”
【发布时间】:2011-06-17 08:30:48
【问题描述】:

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

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

有什么提示吗?

【问题讨论】:

    标签: java generics comparable unchecked


    【解决方案1】:

    您需要像这样“检查”或定义 Comparable 对象:

    add(Comparable<Object> obj)
    

    【讨论】:

      【解决方案2】:

      本质上,此警告表示Comparable 对象不能与任意对象进行比较。 Comparable&lt;T&gt; 是一个泛型接口,其中类型参数T 指定了这个对象可以与之比较的对象的类型。

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

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

      【讨论】:

      • 应该是T extends Comparable&lt;? super T&gt;
      • 为什么是Comparable&lt;? super T&gt;Comparable&lt;T&gt; 似乎还不错。我用它实现了一个二叉搜索树,可以在没有警告的情况下编译它,它可以工作:pastebin.com/Xd78bLC4
      【解决方案3】:

      使用Comparable 之类的接口作为方法参数不会使您的类泛型,声明和使用泛型类型参数是您使其泛型的方式。

      Quick-n-dirty answer:您收到警告是因为您使用的是Comparable,这是一个通用接口,作为原始类型,而不是给它一个特定的类型参数,比如Comparable&lt;String&gt;

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

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

      但是这种快速修复并不能解决您的班级不安全的普遍问题。毕竟,列表中的所有对象不应该是同一类型吗?这个add 方法让您仍然可以将不同的类型放入同一个列表中。当您尝试比较异构类型时会发生什么(您如何将 compareToObject 实例与 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; } 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多