简体   繁体   English

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

[英]Inferred type is not a valid substitute for a Comparable generic type

Consider the code: 考虑一下代码:

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


The sort call gives the error: 排序调用给出错误:

Bound mismatch: The generic method sort(List< T >) of type Collections is not applicable for the arguments (ArrayList< MyItem< T > >). 绑定不匹配:类型集合的泛型方法sort(List <T>)不适用于参数(ArrayList <MyItem <T >>)。 The inferred type MyItem< T > is not a valid substitute for the bounded parameter < T extends Comparable< ? 推断类型MyItem <T>不是有界参数的有效替代<T extends Comparable <? super T > > 超级T >>


Why is this wrong? 为什么这是错的?

If MyItem<V> implements Comparable then why is it not a substitute? 如果MyItem<V>实现Comparable为什么它不能替代?

Sorry if this has been asked, but I feel the question is somewhat specific. 对不起,如果有人询问,但我觉得这个问题有点具体。

Actually more detailed explanation of this error gives your javac itself: 实际上这个错误的更详细的解释给你的javac本身:

java: no suitable method found for sort(java.util.ArrayList<MyItem<V>> ) java:没有为sort(java.util.ArrayList<MyItem<V>>找到合适的方法sort(java.util.ArrayList<MyItem<V>>

method java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>) is not applicable (cannot instantiate from arguments because actual and formal argument lists differ in length) 方法java.util.Collections.<T>sort(java.util.List<T>,java.util.Comparator<? super T>)不适用(无法从参数实例化,因为实际和形式参数列表的长度不同)

method java.util.Collections.<T>sort(java.util.List<T>) is not applicable (inferred type does not conform to declared bound(s) inferred: MyItem<V> bound(s): java.lang.Comparable<? super MyItem<V>> ) 方法java.util.Collections.<T>sort(java.util.List<T>)不适用(推断类型不符合推断的声明边界: MyItem<V> bound(s): java.lang.Comparable<? super MyItem<V>>

So, the main question is: 所以,主要的问题是:
why is method Collections.<T>sort(java.util.List<T>) ) not applicable? 为什么方法Collections.<T>sort(java.util.List<T>) )不适用?

The answer is : 答案是
because in Collections.<T>sort(java.util.List<T>) method declaration there are bounds on parameter T : <T extends Comparable<? super T>> 因为在Collections.<T>sort(java.util.List<T>)方法声明中有参数T界限: <T extends Comparable<? super T>> <T extends Comparable<? super T>> . <T extends Comparable<? super T>>

In another words, T must implement Comparable interface on it self. 换句话说, T必须在其上实现Comparable接口。 For example String class implements such interface: ...implements ... Comparable<String> . 例如, String类实现了这样的接口: ...implements ... Comparable<String>

In your case Item class doesn't implement such interface: 在您的情况下, Item类不实现这样的接口:

Item<T> implements Comparable<T> is not same thing as Item<T> implements Comparable<Item<T>> . Item<T> implements Comparable<T>Item<T> implements Comparable<Item<T>>

So, for solving this problem, your should change your Item class to this one: 因此,要解决此问题,您应该将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
    }
}

For objects of type X to be comparable with each other, class X has to implement exactly Comparable<X> . 对于类型X对象彼此可比较,类X必须实现完全Comparable<X>

This is not what your code is doing, you've got a class Item<T> and you are implementing Comparable<T> instead of Comparable<Item<T>> . 这不是你的代码正在做的事情,你有一个类Item<T> ,你正在实现Comparable<T>而不是Comparable<Item<T>> This means that Item<T> can be compared with T , but not with Item<T> , which is required. 这意味着Item<T>可以与T进行比较,但不能与Item<T> ,这是必需的。

Change your Item<T> class to: 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
    }
}

Just change the class like follow: 只需更改类如下:

     public class MyItem<T> extends Item<String> implement Comparable<MyItem<T>>
     {
         T object;
     }

Or 要么

       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
       }

} }

The error tips has shown us.Hope it helpful. 错误提示向我们展示了。希望它有用。

You do not need to have the class MyItem generified just to see the effect. 您不需要将MyItem类放大,只是为了查看效果。 The following class is enough to see what happens: 以下课程足以看出会发生什么:

public class MyItem extends Item<String> {}

Now you have the following call: 现在您有以下电话:

Collections.sort(list);

As morgano stated correctly, the sort method will take a collection that is parameterized with a type T that must be comparable to T. Your MyItem class is extending Item<String> , which results in MyItem being comparable to String s. 正如morgano所说,sort方法将采用一个类型为T的集合,该类型必须与T相当。您的MyItem类正在扩展Item<String> ,这导致MyItemString s相当。

With a little switch in which class implements the Comparable interface, you will get the expected result: 使用一个实现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
    }
}

And now the call to Collections.sort(list) will work. 现在,对Collections.sort(list)的调用将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM