考虑代码:
public abstract class Item<T> implements Comparable<T>
{
protected T item;
public int compareTo(T o)
{
return 0; // this doesn't matter for the time being
}
}
public class MyItem<T> extends Item<String>
{
T object;
}
public class Foo<T>
{
protected ArrayList<T> list;
}
public class Bar<V> extends Foo<MyItem<V>>
{
public void sort()
{
Collections.sort(list);
}
}
排序调用给出错误:
绑定不匹配:集合类型的泛型方法 sort(List
( 不适用于参数 (ArrayList >(。推断类型 MyItem 不是有界参数的有效替代品, >
为什么这是错误的?
如果MyItem<V>
实现了Comparable
那么为什么它不是替代品呢?
对不起,如果有人问过这个问题,但我觉得这个问题有点具体。
实际上,对此错误的更详细解释给出了您的javac
本身:
Java:没有找到适合
sort(java.util.ArrayList<MyItem<V>>
的方法(方法
java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>)
不适用(无法从参数实例化,因为实际参数列表和正式参数列表的长度不同(方法
java.util.Collections.<T>sort(java.util.List<T>)
不适用(推断类型不符合推断的声明边界:MyItem<V>
边界:java.lang.Comparable<? super MyItem<V>>
(
所以,主要问题是:
为什么方法Collections.<T>sort(java.util.List<T>)
(不适用?
答案是:
因为在Collections.<T>sort(java.util.List<T>)
方法声明中,参数 T
上有边界:<T extends Comparable<? super T>>
。
换句话说,T
必须在其自身上实现Comparable
接口。例如String
类实现了这样的接口:...implements ... Comparable<String>
。
在您的情况下Item
类没有实现这样的接口:
Item<T> implements Comparable<T>
与Item<T> implements Comparable<Item<T>>
不是一回事。
因此,为了解决此问题,您应该将Item
类更改为以下类:
public abstract class Item<T> implements Comparable<Item<T>>
{
protected T item;
public int compareTo(Item<T> o)
{
return 0; // this doesn't matter for the time being
}
}
为了使 X
类型的对象彼此比较,类 X
必须完全Comparable<X>
实现。
这不是你的代码正在做的事情,你有一个类Item<T>
并且你正在实现Comparable<T>
而不是Comparable<Item<T>>
。这意味着Item<T>
可以与T
进行比较,但不能与Item<T>
进行比较,这是必需的。
将Item<T>
类更改为:
public abstract class Item<T> implements Comparable<Item<T>>
{
protected T item;
@Override
public int compareTo(Item<T> o)
{
return 0; // this doesn't matter for the time being
}
}
只需像下面这样更改类:
public class MyItem<T> extends Item<String> implement Comparable<MyItem<T>>
{
T object;
}
或
public abstract class Item<T> implements Comparable<MyItem<T>>
{
protected T item;
public int compareTo(MyItem<T> o)
{
return 0; // this doesn't matter for the time being
}
}
错误提示已经向我们展示了。希望对您有所帮助。
您不需要为了看到效果而使类MyItem
泛化。以下类足以看到会发生什么:
public class MyItem extends Item<String> {}
现在您有以下调用:
Collections.sort(list);
正如 morgano 正确指出的那样,排序方法将采用一个集合,该集合使用必须与 T 相当的类型 T 进行参数化。您的MyItem
类正在扩展Item<String>
,这导致MyItem
与String
相当。
只需在哪个类中实现Comparable
接口,您将获得预期的结果:
public abstract class Item<T> {
protected T item;
}
public class MyItem extends Item<String> implements Comparable<MyItem> {
@Override
public int compareTo(MyItem o) {
return item.compareTo(o.item); // just an example
}
}
现在,对Collections.sort(list)
的呼吁将起作用。