Upper Bounded Wildcards

我们能使用上边界通配符来放松一个变量的限制。比如说,你想要写一个函数对于List<Integer>, List<Double>,List<Number> 功能使用,你可以使用上边界通配符打到目的。

定义一个上边界通配符时使用通配字符?,后面紧跟extends关键字,最后是它的upper bound(上边界)。请注意,在这语境中,extends被用在一个普通场景表示对类的extends(扩展)或者对接口的implements(实现)。

为了编写的函数可以同时作用于Number类型及其子类型(Integer,Double,Float)的列表,你可以指定List<? extends Number>List<Number>List<? extends Number>更有限制性,因为它只能适用于Number类型的列表,而后者适用于Number类型及其子类型的列表。

以下面的process函数为例:

public static void process(List<? extends Foo> list) { /* ... */ }

上边界通配符<? extends Foo>,无论Foo是何类型,匹配Foo类型以及它的子类型。process函数可以以Foo类型访问列表元素:

public static void process(List<? extends Foo> list) {
    for (Foo elem : list) {
        // ...
    }
}

foreach条件中,变量elem遍历列表中的每个元素。任何Foo类中定义的函数都能被elem使用。

函数sumOfList返回列表中数字的和:

public static double sumOfList(List<? extends Number> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

下面这段代码使用Integer实例的列表,打印sum = 6.0:

List<Integer> li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfList(li));

Double类型的列表也同样适用于sumOfList,下面这段代码打印sum = 7.0

List<Double> ld = Arrays.asList(1.2, 2.3, 3.5);
System.out.println("sum = " + sumOfList(ld));

Last updated