具有通用参数的 compareTo 发出警告
compareTo with generic arguments is giving warning
我想比较 less 方法中的两个 Comparable 类型的参数。但是,如果我使用 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;
}
最初的错误是正确的,警告是正确的:你的技巧非常不安全:你不能将 v 转换为 T。
因为您的方法有两个参数 u 和 v,每个参数都是 class 的一个实例,它实现了 compareTo(T 的某个实例)。
准确地说:u可以比T,v可以比T。
但是,在内部,你想比较u和v。绝对没有保证你可以做到。
例如,这是正确的:
private static <X> boolean less(Comparable<X> u, X v)
{
return u.compareTo(v) < 0;
}
由于 u
的类型为 Comparable<T>
,u.compareTo()
采用 T
。您正在传递它 v
,一个 Comparable<T>
,这是不兼容的。
您可能会在脑海中假设实现 Comparable
的类型与其自身具有可比性。但是在技术层面上没有这样的要求。我创建类型 Foo
是完全合法的,即 Comparable<Bar>
,即它与 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;
}
在您的评论中,您提到您正在比较 Comparable<T>[]
中的元素。那不是一种允许您比较元素的数组类型。你只知道它是一个元素数组,与某个 T
可比,但与自身不可比。更有用的是 T[]
,其中 T
有一个界限,它可以与自身相媲美:
class Whatever<T extends Comparable<? super T>> {
//...
T[] yourArray;
}
我想比较 less 方法中的两个 Comparable 类型的参数。但是,如果我使用 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;
}
最初的错误是正确的,警告是正确的:你的技巧非常不安全:你不能将 v 转换为 T。
因为您的方法有两个参数 u 和 v,每个参数都是 class 的一个实例,它实现了 compareTo(T 的某个实例)。
准确地说:u可以比T,v可以比T。
但是,在内部,你想比较u和v。绝对没有保证你可以做到。
例如,这是正确的:
private static <X> boolean less(Comparable<X> u, X v)
{
return u.compareTo(v) < 0;
}
由于 u
的类型为 Comparable<T>
,u.compareTo()
采用 T
。您正在传递它 v
,一个 Comparable<T>
,这是不兼容的。
您可能会在脑海中假设实现 Comparable
的类型与其自身具有可比性。但是在技术层面上没有这样的要求。我创建类型 Foo
是完全合法的,即 Comparable<Bar>
,即它与 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;
}
在您的评论中,您提到您正在比较 Comparable<T>[]
中的元素。那不是一种允许您比较元素的数组类型。你只知道它是一个元素数组,与某个 T
可比,但与自身不可比。更有用的是 T[]
,其中 T
有一个界限,它可以与自身相媲美:
class Whatever<T extends Comparable<? super T>> {
//...
T[] yourArray;
}