可比药物和通配符仿制药
假设我有以下类(用于演示目的)
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
类型中的方法compareTo(capture#1-of ?) 不适用于参数 (Comparable
)"
我该如何处理我想将不同的 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
,那么编译器会抱怨(如上所述),因为两个强制转换操作不能保证是同一类(capture#1 of ? vs capture#2 of ?)。另一方面,我也不能用 Comparable
Suppose I have the following class (for demonstration purposes)
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;
}
}
The compiler tells me
"The method compareTo(capture#1-of ?) in the type
Comparable<capture#1-of ?>
is not applicable for the arguments (Comparable<capture#2-of ?>
)"
How can I deal with the fact that I want to put different Comparables
into trains?
Sure I could remove the parameters and go with raw types, but that seems like a little bit of a cop-out.
EDIT:
Perhaps the example I've given is a little obtuse. What I'm trying to understand is whether generics should always be used with Comparables
. e.g. If the class of the object I want compare is not known until runtime:
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)));
}
}
If I replace Comparable
with Comparable<?>
then the compiler complains (as above) because the two cast operations are not guaranteed to be the same class (capture#1 of ? vs capture#2 of ?). On the other hand, I can't replace them with Comparable<Object>
either, because then the call in main()
doesn't match the method signature (i.e. Integer
implements Comparable<Integer>
and not Comparable<Object>
. Using the raw type certainly 'works', but is this the right approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于,一个实例可能具有将不接受
Comparable
,而另一个实例包含Comapable
以及compare
方法ComparableTrainB
的实例。这就是您使用通配符设置的内容。更好的选择是在 Comparable 中放置一个通用的超类型。
Comparable
或Comparable。
The problem is that one instance might have a
Comparable<TrainA>
and the other containComapable<TrainB>
and thecompare
method ofComparable<TrainA>
will not accept an instance ofTrainB
. This is what you have set up with the wildcard.Your better bet is to put a common super type in the
Comparable
ie.Comparable<Toy>
orComparable<Object>
.通过将
trains
字段声明为Comparable[]
类型,您就断言它是某种特定类型的数组,而您并不这样做碰巧知道它是什么类型。Toyset
的两个不同实例均具有trains
字段,用于保存某种特定类型的序列,但每个实例都有不同 > 牢记特定类型。编译器警告您,代码中没有任何内容断言指向Toyset
实例中的各种trains
字段的数组的特定类型将具有任何子类型或超类型关系。在这种情况下,回到原始类型是诚实的;对于所比较的对象类型,您没有任何有意义的说法。您可以尝试使用
Comparable,它允许使用相当弱的类型参数。
这个设计让我觉得很奇怪。我假设它被更大的东西删除了。玩具组可以进行比较,这又取决于每个玩具组中包含的火车的字典顺序比较。这很好,但为什么所有列车都没有共同的上限类型呢?
By declaring your
trains
field to be of typeComparable<?>[]
, you're asserting that it's an array of some specific type—and that you don't happen to know which type it is. Two different instances ofToyset
will each havetrains
fields that hold sequences of some specific type, but each has a different specific type in mind. The compiler is warning you that there's nothing in the code asserting that the specific types of the arrays pointed to be the varioustrains
fields inToyset
instances will have any subtype or supertype relationship.In this case, falling back to a raw type is honest; you don't have anything meaningful to say about the type of objects being compared. You could instead try using
Comparable<Object>
, which allows rather weak use of a type parameter.The design strikes me as odd. I'm assuming it's elided from something much larger. Toy sets can be compared, which in turn depends on a lexicographic comparison of the trains contained in each toy set. That's fine, but why is there no upper bound type that all trains have in common?