상위 제한된 와일드 카드 Upper Bounded Wildcards

변수에 완화된 제한을 걸고 싶을때 upper bounded wildcard를 사용한다. 예를들면, List<Integer>, List<Double>, List<Number> 타입들에서 동작하는 메서드를 작성할때 upper bounded wildcard를 사용해서 만들수 있다.
You can use an upper bounded wildcard to relax the restrictions on a variable. For example, say you want to write a method that works on List, List, and List; you can achieve this by using an upper bounded wildcard.

uppper-bounded wildcard는 와일드카드 문자 ‘?‘와 뒤에는 extends 키워드를 사용하고 뒤에는 상위 타입을 써서 정의한다. 클래스의 extends, 인터페이스의 implements처럼 extends 키워드는 이러한 의미로 사용된다.
To declare an upper-bounded wildcard, use the wildcard character (‘?’), followed by the extends keyword, followed by its upper bound. Note that, in this context, extends is used in a general sense to mean either “extends” (as in classes) or “implements” (as in interfaces).

Integer, Double, Float처럼 Number 타입의 서브타입들에서 동작하는 메서드를 작성할 때, List<? extends Number> 요래 작성하면된다. List<Number>는 List<? extends Number>보다 제한적이다. 전자는 Number 타입의 리스트만 가능, 후자는 Number 타입 또는 Number 타입의 서브 타입 리스트도 가능하다.
To write the method that works on lists of Number and the subtypes of Number, such as Integer, Double, and Float, you would specify List<? extends Number>. The term List is more restrictive than List<? extends Number> because the former matches a list of type Number only, whereas the latter matches a list of type Number or any of its subclasses.

아래의 process 메서드를 살펴보자
Consider the following process method:

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

<? extends Foo> upper bounded wildcard는 Foo와 Foo의 서브타입과 매치되는 표현이다. (아래의 코드 참조)process 메서드는 Foo타입과 같은 리스트의 요소를 엑세스할수 있다.
The upper bounded wildcard, <? extends Foo>, where Foo is any type, matches Foo and any subtype of Foo. The process method can access the list elements as type Foo:

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

foreach절은 list의 각각 요소를 순회하며 elem 변수에 할당한다. elem은 Foo 클래스에 정의되어 있는 메서드를 모두 사용할 수 있다.
In the foreach clause, the elem variable iterates over each element in the list. Any method defined in the Foo class can now be used on elem.

sumOfList메서드는 리스트 안의 숫자의 합을 리턴한다.
The sumOfList method returns the sum of the numbers in a list:

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”을 출력한다.
The following code, using a list of Integer objects, prints sum = 6.0:

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

Double값을 가진 리스트도 sumOfList 메서드를 역시 사용할 수 있다. 아래의 코드는 “sum = 7.0”을 출력한다.
A list of Double values can use the same sumOfList method. The following code prints sum = 7.0:

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