可比兼容和通配符泛型

时间:2011-11-14 19:21:14

标签: java generics comparable

假设我有以下课程(用于演示目的)

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>。使用原始类型肯定“有效”,但这是正确的方法吗?

2 个答案:

答案 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>,它允许使用类型参数。

设计让我觉得奇怪。我假设它从更大的东西中消失了。可以比较玩具组,这又取决于每个玩具组中包含的列车的字典比较。这很好,但为什么没有上限类型,所有列车都有共同点?