编译器认为可比类型不可比

时间:2014-05-02 02:31:42

标签: java generics interface comparable

所以我有一个实现Comparable的类(为了简洁我在这里有一个虚拟方法)

public class MarkovEntry<T extends Chainable> implements Comparable<MarkovEntry<T>>
{
    // Compare two rows by ID
    public int compareTo(MarkovEntry<T> e)
    {
        return 0;
    }
}

另一个类中的方法采用Comparable(再次,虚拟方法)

public class ArrayOps
{
    public static int binSearch(ArrayList<Comparable> list, Comparable c)
    {
        return 0;
    }
}

然而,当我尝试按如下方式调用我的方法时

int index = ArrayOps.binSearch(entries, newEntry);

其中entries是MarkovEntry的ArrayList,newEntry是MarkovEntry,编译器告诉我

actual argument java.util.ArrayList<com.company.MarkovEntry<T>> cannot be converted 
to java.util.ArrayList<java.lang.Comparable> by method invocation.

这里发生了什么? MarkovEntry专门实现了Comparable - 为什么编译器不能识别?

我的类Chainable也实现了Comparable,如果它与它有任何关系。

1 个答案:

答案 0 :(得分:5)

泛型有点奇怪

ArrayList<SuperType>

实际上不是

的超类型
ArrayList<SubType>

e.g。 ArrayList<Number>不是ArrayList<Integer>的超类型。这是因为如果这种关系持有你可以用ArrayList<Number>代替ArrayList<Integer>,那么如果你不进行替换就会允许那些非法的操作。

更具体地说,你这样做了:

ArrayList<Number> list = new ArrayList<Integer>();

然后,您可以将Double放入list,因为编译器listArrayList<Number>!正如您所看到的,这打破了泛型应该提供的保证,因此不允许这样做。


您正在寻找的是泛型方法,如下所示:

public static <T extends Comparable<? super T>> int binSearch(ArrayList<T> list)

基本上,您可以使用与生成类相同的方式生成方法。

可以在此处找到更多信息:http://docs.oracle.com/javase/tutorial/extra/generics/methods.html