推断类型不是Comparable泛型类型的有效替代

时间:2013-07-19 06:48:38

标签: java generics collections

考虑代码:

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调用给出了错误:

  

绑定不匹配:类型集合的通用方法sort(List&lt; T&gt;)不适用于参数(ArrayList&lt; MyItem&lt; T&gt;&gt;)。推断类型MyItem&lt; T>不是有界参数的有效替代品&lt; T扩展可比较&lt; ?超级T&gt; &GT;


为什么这是错的?

如果MyItem<V>实施Comparable那么为什么它不能替代?

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

4 个答案:

答案 0 :(得分: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> bound(s):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
    }
}

答案 1 :(得分: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
    }
}

答案 2 :(得分: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
       }

}

错误提示向我们展示。希望它有用。

答案 3 :(得分:0)

您不需要将类MyItem一般化即可查看效果。以下课程足以看出会发生什么:

public class MyItem extends Item<String> {}

现在您有以下电话:

Collections.sort(list);

正如morgano所说,sort方法将采用一个参数化的集合,该类型T必须与T相当。您的MyItem类正在扩展Item<String>,这导致{{1可与MyItem s相媲美。

使用一个小类实现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 } } 即可。