【问题标题】:compareTo with generic arguments is giving warning带有泛型参数的 compareTo 发出警告
【发布时间】:2015-12-06 16:43:21
【问题描述】:

我想比较比较类型为 Comparable 的 less 方法中的两个参数。但是如果我使用comapreTo,它会在类型转换中给我错误:

private boolean less(Comparable<T> u, Comparable<T> v) {
    return u.compareTo(v) < 0;
}

我通过类型转换传递给 compareTo 的参数解决了这个问题。但它仍然给我警告(类型安全:从 Comparable 到 T 的未经检查的转换)。为什么会这样。难道我做错了什么。实现这一目标的最佳方法是什么。

private boolean less(Comparable<T> u, Comparable<T> v) {
    return u.compareTo((T) v) < 0;
}

【问题讨论】:

  • 也许我只是缺少上下文,但它不应该更像private boolean less(Comparable&lt;T&gt; u, T v) {吗?既然您要比较 U 和 V 类型的 T ...?
  • T extends Comparable 我想比较两个 Comparable 类型的参数。
  • 但是Comparable 只定义了一个方法compareTo(T)。您要比较的值必须与Comparable 期望的类型相同。你的方法实际上看起来更像private &lt;T extends Comparable&gt; boolean less(Comparable&lt;T&gt; u, T v) {?!?对我来说,这毫无意义
  • 我有一个 Comparable 对象数组,如果没有这个,我将如何比较它们。你能推荐我吗?
  • 我认为你混淆了这个问题。你有一个Comparable&lt;T&gt; 的数组,所以我假设你有一个T 的实例,你想比较数组中的每个元素吗?然后private boolean less(Comparable&lt;T&gt; u, T v) { 就可以了

标签: java generics comparison


【解决方案1】:

由于u 具有Comparable&lt;T&gt; 类型,u.compareTo() 采用T。您将其传递给 v,Comparable&lt;T&gt;,这是不兼容的。

您可能会在脑海中假设实现Comparable 的类型与其自身具有可比性。但在技术层面上没有这样的要求。对我来说,创建 Foo 类型是完全合法的,即 Comparable&lt;Bar&gt;,即它与 Bar 相比,其中 Foo 和 Bar 完全不相关。尝试将 Foo 传递给 Foo 对象的 compareTo 会崩溃。

如果您想限制两个参数的类型相同且可与自身进行比较,您可以执行类似的操作

private <T extends Comparable<? super T>> boolean less(T u, T v) {
    return u.compareTo(v) < 0;
}

然而,就这个函数而言,两个参数属于同一类型的约束在技术上是不必要的(尽管在所有正常用例中都应该如此)。在泛型中,我们总是希望尽可能使用限制最少的界限,正如其他答案所提到的,

private <T> boolean less(Comparable<T> u, T v) {
    return u.compareTo(v) < 0;
}

在您的 cmets 中,您提到您正在比较来自 Comparable&lt;T&gt;[] 的元素。这不是一种允许您比较元素的数组类型。你只知道它是一个元素数组,可以和某个T比较,但不能和自己比较。更有用的是有一个T[],其中T 有一个与自身相当的界限:

class Whatever<T extends Comparable<? super T>> {
    //...
    T[] yourArray;
}

【讨论】:

    【解决方案2】:

    最初的错误是正确的,警告是正确的:你的把戏非常不安全:你不能将 v 转换为 T。

    因为你的方法有两个参数 u 和 v,每一个都是一个类的实例,它实现了 compareTo(T 的某个实例)。

    准确地说:u 可以和 T 比较,v 可以和 T 比较。

    但是,在里面,你想比较 u 和 v。绝对没有保证可以做到。

    例如,这是正确的:

    private static <X> boolean less(Comparable<X> u, X v)
        {
        return u.compareTo(v) < 0;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多