我能否将以下代码转换为使用泛型?

18

我正在将一个应用程序转换为使用Java 1.5,并发现了以下方法:

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2
   */
  protected static int nullCompare(Comparable o1, Comparable o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }

理想情况下,我希望该方法接受两个相同类型的可比较对象,是否可以转换并如何操作?我认为以下代码可以解决问题:
protected static <T extends Comparable> int nullCompare(T o1, T o2) {

但它未能消除IntelliJ上的警告:“作为原始类型'java.lang.Comparable'的成员,对'compareTo(T)'的未检查调用” ,该警告出现在以下行中:

return o1.compareTo(o2);
5个回答

21

将其更改为:

protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) {

你需要这样做是因为Comparable本身就是一个泛型类型。


啊!我简直不敢相信我离成功那么近了。 - Steve Bosman
你确定 T extends Comparable<T> 是正确的吗?似乎 T extends Comparable<?> 更加准确? - cletus
@cletus:T extends Comparable<T> 是正确的。如果在排序时一个 Foo 对象可以与一个 Bar 对象进行比较,那是没有帮助的。 - wchargin

5

以下是一个奇怪的案例:

static class A {
    ...
}

static class B extends A implements Comparable<A> {
    public int compareTo(A o) {
        return ...;
    }
}

幸运的是,像上面那样的代码很少见,但是 nullCompare() 将不支持 B 的比较,除非声明 Comparable 可以应用于 T 或其任何超类:
protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

尽管大多数人可能永远不会从上述调整中受益,但在设计导出库的API时可能会派上用场。

2

由于Comparable是泛型,所以需要声明嵌套类型参数。

无法编辑,因此我必须发布我的答案。

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {

请注意,Comparable< ? super T > 更加灵活。在 Collections.sort 方法定义中会看到相同的方法定义。
public static <T extends Comparable<? super T>> void sort(List<T> list) {

0

为了让它更加通用,你甚至可以让它适用于两种不同的类型。=P

  /**
   * Compare two Comparables, treat nulls as -infinity.
   * @param o1
   * @param o2
   * @return -1 if o1&lt;o2, 0 if o1==o2, 1 if o1&gt;o2
   */
  protected static <T> int nullCompare(Comparable<? super T> o1, T o2) {
    if (o1 == null) {
      if (o2 == null) {
        return 0;
      } else {
        return -1;
      }
    } else if (o2 == null) {
      return 1;
    } else {
      return o1.compareTo(o2);
    }
  }

0

我不确定泛型化这个方法是否有意义。目前该方法适用于任何类型的Comparable;如果你泛型化它,你将不得不多次实现它(使用完全相同的代码)。有时可以比较两个没有共同祖先的对象,而任何泛型版本都不允许这样做。

通过添加泛型,您不会为代码添加任何安全性;任何安全问题都将出现在调用compareTo中。我建议的是简单地抑制警告。它并没有真正警告你任何有用的信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接