compareTo与泛型参数发出警告

时间:2015-12-02 06:03:06

标签: java generics comparison

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

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

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

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

2 个答案:

答案 0 :(得分:1)

初始错误是正确的,并且警告是正确的:你的技巧非常不安全:你不能把v投射到T.

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

确切地说:你可以比较T,v可以比较T。

但是,在内部,你想要比较你和v。绝对没有保证你能做到。

例如,这是正确的:

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

答案 1 :(得分:1)

由于strnew = strnew + " ";的类型为uComparable<T>需要u.compareTo()。您正在传递Tv,这是不兼容的。

您可能会在脑海中假设实现Comparable<T>的类型与其自身相当。但是在技术层面上没有这样的要求。制作Comparable类型Foo对我来说是完全合法的,即它与Comparable<Bar>进行比较,其中BarFooBar完全无关。尝试将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;
}

在您的评论中,您提到您正在比较Comparable<T>[]中的元素。这不是一种允许您比较元素的数组。您只知道它是一系列与某个T相当的元素,但与自身无法比较。更有用的是拥有T[],其中T具有与其自身相当的界限:

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