在Java泛型中如何使用逆变? [英] How would contravariance be used in Java generics?
问题描述
在Java中,协方差允许API设计者指定一个实例可以被推广为某种类型或任何类型的子类型。例如:
In Java, covariance allows the API designer to specify that an instance may be generalised as a certain type or any of that type's subtypes. For example:
List<? extends Shape> shapes = new ArrayList<Circle>();
// where type Circle extends Shape
反向变换是另一种方式。它允许我们指定一个实例可以泛化为某种类型或超类型。
Contravariance goes the other way. It allows us to specify that an instance may be generalised as a certain type or supertype.
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry
Java泛型的逆变是如何有用的?你什么时候选择使用它?
How is Java generic's contravariance useful? When would you choose to use it?
推荐答案
好吧,你的第二个例子可以让你编写:
Well, your second example would allow you to write:
Shape shape = getShapeFromSomewhere();
shapes.add(shape);
而第一种形式则无法做到这一点。它不像协变性那样有用,我会授予你的。
whereas you couldn't do that with the first form. It's not useful as often as covariance, I'll grant you.
可以用 的一个区域用于比较。例如,考虑:
One area where it can be useful is in terms of comparisons. For example, consider:
class AreaComparer implements Comparator<Shape>
...
您可以使用它来比较任何两种形状......因此,如果我们还可以 使用它对 List< Circle>
进行排序,那将会很好。幸运的是,我们可以通过逆变来做到这一点,这就是为什么 Collections.sort
的重载:
You can use that to compare any two shapes... so it would be nice if we could also use it to sort a List<Circle>
for example. Fortunately, we can do that with contravariance, which is why there's an overload for Collections.sort
of:
public static <T> void sort(List<T> list, Comparator<? super T> c)
这篇关于在Java泛型中如何使用逆变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!