2

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

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

编译器告诉我

“类型中的方法 compareTo(capture#1-of ?)Comparable<capture#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>。使用原始类型肯定“有效”,但这是正确的方法吗?

4

2 回答 2

4

问题是一个实例可能有一个Comparable<TrainA>,而另一个包含Comapable<TrainB>,并且该compare方法Comparable<TrainA>将不接受一个实例TrainB。这就是您使用通配符设置的内容。

您最好的选择是在Comparableie 中放置一个常见的超级类型。Comparable<Toy>Comparable<Object>

于 2011-11-14T19:34:20.993 回答
0

通过将你的trains字段声明为 type Comparable<?>[],你就断言它是一个特定类型的数组——而且你碰巧不知道它是哪种类型。will的两个不同实例Toyset每个都有包含某些特定类型trains序列的字段,但每个实例都有不同的特定类型。编译器警告您,代码中没有任何内容断言指向实例中各种字段的数组的特定类型将具有任何子类型或超类型关系。trainsToyset

在这种情况下,回退到原始类型是诚实的;对于被比较的对象的类型,您没有任何有意义的说法。您可以改为尝试 using Comparable<Object>,它允许相当弱地使用类型参数。

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

于 2011-11-14T20:23:46.103 回答