首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Java泛型中使用逆变?

如何在Java泛型中使用逆变?
EN

Stack Overflow用户
提问于 2010-10-05 13:54:00
回答 3查看 6.9K关注 0票数 28

在Java中,协方差允许API设计者指定一个实例可以泛化为某个类型或该类型的任何子类型。例如:

代码语言:javascript
复制
List<? extends Shape> shapes = new ArrayList<Circle>(); 
// where type Circle extends Shape

逆方差则相反。它允许我们指定一个实例可以被泛化为某个类型或超类型。

代码语言:javascript
复制
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry

Java泛型的逆变有什么用处?你会选择什么时候使用它?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-05 13:58:25

那么,您的第二个示例将允许您编写:

代码语言:javascript
复制
Shape shape = getShapeFromSomewhere();
shapes.add(shape);

而你不能用第一种形式做到这一点。它不像协方差那么有用,我承认。

它可能有用的一个领域是在比较方面。例如,考虑以下内容:

代码语言:javascript
复制
class AreaComparer implements Comparator<Shape>
...

你可以用它来比较任何两个形状..。因此,如果我们也能用它来对List<Circle>进行排序,那就太好了。幸运的是,我们可以使用逆方差来做到这一点,这就是为什么Collections.sort会重载:

代码语言:javascript
复制
public static <T> void sort(List<T> list, Comparator<? super T> c)
票数 33
EN

Stack Overflow用户

发布于 2010-10-05 20:10:02

以下是来自Java Generics and Collections的相关摘录

2.4。Get和Put原则

尽可能插入通配符可能是一种很好的做法,但是如何决定使用哪个通配符呢?你应该在哪里使用extends,你应该在哪里使用super,在哪里使用通配符是不合适的?

幸运的是,一个简单的原则决定了哪一个是合适的。

Get put Principle:当只从结构中获取值时,使用extends通配符;当只将值放入结构中时,使用super通配符;当同时获取和放置值时,不要使用通配符。

我们已经在copy方法的签名中看到了这个原则:

代码语言:javascript
复制
public static <T> void copy(List<? super T> dest, List<? extends T> src)

该方法从源源src获取值,因此使用dst通配符声明它,并将值放入目标extends中,因此它使用super通配符声明。每当使用迭代器时,都会从结构中获取值,因此请使用extends通配符。下面是一个方法,它接受一个数字集合,将每个数字转换为双精度数,然后对它们求和:

代码语言:javascript
复制
public static double sum(Collection<? extends Number> nums) {
    double s = 0.0;
    for (Number num : nums) s += num.doubleValue();
    return s;
}
票数 36
EN

Stack Overflow用户

发布于 2010-10-05 14:02:42

例如,在实现Collections.addAll()方法时,您需要一个可以包含某种类型T或T的超类型的集合。该方法如下所示:

代码语言:javascript
复制
public static <T> void addAll(Collection<? super T> collection, T... objects) {
    // Do something
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3861132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档