在 Java 中,协变允许 API 设计者指定可以将实例概括为某种类型或该类型的任何子类型。例如:
List<? extends Shape> shapes = new ArrayList<Circle>();
// where type Circle extends Shape
逆变则相反。它允许我们指定一个实例可以被泛化为某种类型或超类型。
List<? super Shape> shapes = new ArrayList<Geometry>();
// where Shape extends Geometry
Java 泛型逆变有何用处?您什么时候会选择使用它?
这是相关摘录Java 泛型和集合 http://oreilly.com/catalog/9780596527754:
2.4.获取和放置原则
尽可能插入通配符可能是一个好习惯,但是您如何决定
使用哪个通配符?你应该在哪里使用extends
,你应该在哪里使用super
,
哪些地方不适合使用通配符?
幸运的是,有一个简单的原则可以决定哪种方法是合适的。
获取和放置原则:使用extends
当你只得到通配符
结构中的值,使用super
当您仅将值放入时通配符
结构体,并且不使用通配符
当你同时获取和放置时。
我们已经在 copy 方法的签名中看到了这一原则的作用:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
该方法从源 src 中获取值,因此它是用extends
通配符,
并将值放入目标 dst,因此它是用 a 声明的super
通配符。
每当您使用迭代器时,您都会从结构中获取值,因此请使用extends
通配符。这是一个方法,它接受数字集合,将每个数字转换为双精度值,
并总结它们:
public static double sum(Collection<? extends Number> nums) {
double s = 0.0;
for (Number num : nums) s += num.doubleValue();
return s;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)