14

考虑代码:

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);
    }
}


排序调用给出了错误:

绑定不匹配:Collections 类型的泛型方法 sort(List< T >) 不适用于参数 (ArrayList< MyItem< T > >)。推断的类型 MyItem< T > 不是有界参数 < T extends Comparable< 的有效替代品?超级T > >


为什么这是错误的?

如果MyItem<V>实现Comparable了,为什么它不是替代品?

抱歉,如果有人问过这个问题,但我觉得这个问题有些具体。

4

4 回答 4

12

实际上,这个错误的更详细解释给了你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>>:)

所以,主要问题是:
为什么 method 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
    }
}
于 2013-07-19T07:20:59.667 回答
2

为了使类型的对象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
    }
}
于 2013-07-19T07:31:00.243 回答
1

只需更改类如下:

     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
       }

}

错误提示已向我们展示。希望对您有所帮助。

于 2013-07-19T07:30:50.393 回答
0

您不需要MyItem为了查看效果而对类进行泛化。下面的类足以看看会发生什么:

public class MyItem extends Item<String> {}

现在您有以下调用:

Collections.sort(list);

正如 morgano 正确指出的那样,sort 方法将采用一个参数化的集合,该集合使用必须与 T 可比较的类型 T。您的MyItem类正在扩展Item<String>,这导致MyItemStrings 可比较。

稍微切换一下哪个类实现了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)将起作用。

于 2013-07-19T07:25:08.003 回答