所以我有一个实现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,如果它与它有任何关系。
答案 0 :(得分:5)
泛型有点奇怪
ArrayList<SuperType>
实际上不是
的超类型ArrayList<SubType>
e.g。 ArrayList<Number>
不是ArrayList<Integer>
的超类型。这是因为如果这种关系持有你可以用ArrayList<Number>
代替ArrayList<Integer>
,那么如果你不进行替换就会允许那些非法的操作。
更具体地说,你这样做了:
ArrayList<Number> list = new ArrayList<Integer>();
然后,您可以将Double
放入list
,因为编译器list
是ArrayList<Number>
!正如您所看到的,这打破了泛型应该提供的保证,因此不允许这样做。
您正在寻找的是泛型方法,如下所示:
public static <T extends Comparable<? super T>> int binSearch(ArrayList<T> list)
基本上,您可以使用与生成类相同的方式生成方法。
可以在此处找到更多信息:http://docs.oracle.com/javase/tutorial/extra/generics/methods.html