在Java泛型中如何使用逆变? [英] How would contravariance be used in Java generics?

查看:102
本文介绍了在Java泛型中如何使用逆变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆