假设我有以下课程(用于演示目的)
package flourish.lang.data;
public class Toyset implements Comparable<Toyset> {
private Comparable<?>[] trains;
@Override
public int compareTo(Toyset o) {
for (int i =0; i<trains.length; i++) {
if (trains[i].compareTo(o.trains[i]) < 0)
return -1;
}
return 1;
}
}
编译器告诉我
“类型
Comparable<capture#1-of ?>
中的方法compareTo(捕获#1-of?)不适用于参数(Comparable<capture#2-of ?>
)”
我如何处理我想将不同Comparables
放入火车的事实?
当然,我可以删除参数并使用原始类型,但这似乎是一个小问题。
编辑:
也许我给出的例子有点迟钝。我想要了解的是,泛型是否应该始终与Comparables
一起使用。例如如果我想要比较的对象的类在运行时才知道:
public class ComparisonTool {
public static int compareSomeObjects(final Class<? extends Comparable> clazz, final Object o1, final Object o2) {
return clazz.cast(o1).compareTo(clazz.cast(o2));
}
public static void main(String[] args) {
System.out.println(compareSomeObjects(Integer.class, new Integer(22), new Integer(33)));
}
}
如果我用Comparable
替换Comparable<?>
,那么编译器会抱怨(如上所述),因为两个强制转换操作不能保证是同一个类(捕获#1 of?vs capture#2 of? )。另一方面,我也无法用Comparable<Object>
替换它们,因为main()
中的调用与方法签名不匹配(即Integer
实现Comparable<Integer>
和不是Comparable<Object>
。使用原始类型肯定“有效”,但这是正确的方法吗?
答案 0 :(得分:4)
问题是,一个实例可能包含Comparable<TrainA>
而另一个实例包含Comapable<TrainB>
,而compare
Comparable<TrainA>
方法不会接受TrainB
的实例}。这是您使用通配符设置的内容。
你最好的选择是在Comparable
中加入一个普通的超类型。 Comparable<Toy>
或Comparable<Object>
。
答案 1 :(得分:0)
通过声明您的trains
字段属于Comparable<?>[]
类型,您声明它是某个特定类型的数组 - 并且您不会发生这种情况知道是哪种类型。 Toyset
的两个不同实例每个都有trains
个字段,其中包含某些特定类型的序列,但每个字段都有一个不同的特定类型。编译器警告您,代码中没有任何内容断言,指向trains
个实例中的各个Toyset
字段的特定类型的数组将具有任何子类型或超类型关系。< / p>
在这种情况下,回归原始类型是诚实的;你对所比较的物体类型没有任何意义。您可以尝试使用Comparable<Object>
,它允许使用类型参数。
设计让我觉得奇怪。我假设它从更大的东西中消失了。可以比较玩具组,这又取决于每个玩具组中包含的列车的字典比较。这很好,但为什么没有上限类型,所有列车都有共同点?