Java
Wildcard
Learn wildcard types ? extends T and ? super T.
Wildcard types
For generic types you use the wildcard ?. There are three forms: <?> an unknown type, <? extends T> T and its subtypes (upper bound), <? super T> T and its supertypes (lower bound).
For example static double sum(List<? extends Number> nums) accepts List<Integer>, List<Double> and other lists of Number subtypes. Wildcards are the key to flexible generic collections; they provide covariance and contravariance.
The PECS principle
The PECS principle helps choose wildcards: Producer Extends, Consumer Super. If a list is a producer (you read from it) use ? extends T; if it is a consumer (you write to it) use ? super T.
For example sum(List<? extends Number>) reads numbers, so it is a producer. addNumbers(List<? super Integer>) adds Integers, so it is a consumer. When you need both directions you write a generic method <T> instead.
Exercise Write the sum wildcard method
Define static double sum(List<? extends Number> nums). In the body loop with for (Number n : nums) total += n.doubleValue(); and return total;. In main, create a list with List<Integer> ints = Arrays.asList(1, 2, 3); and print System.out.println(sum(ints));.
Show example solution
import java.util.List;
import java.util.Arrays;
public class Main {
static double sum(List<? extends Number> nums) {
double total = 0;
for (Number n : nums) {
total += n.doubleValue();
}
return total;
}
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(1, 2, 3);
System.out.println(sum(ints));
}
}
Test yourself
-
What does List<? extends Number> accept?
- Only List<Number>
- List<Integer> and List<Double> like Number subtypes
- Only List<Object>
- Any List type
Show answer
Only List<Object> — ? extends Number accepts lists of Number and its subtypes.
-
Match the wildcard concepts
- ? extends T
- Producer (covariant)
- ? super T
- Consumer (contravariant)
- ?
- Unknown type
- extends
- Upper bound keyword
-
Complete the wildcard parameter
static double sum(List____ nums) {
double total = 0;
return total;
}
Show answer
static double sum(List<? extends Number> nums) {
double total = 0;
return total;
}
Next lesson: Type erasure