What it is and why to use it
List<Integer> is not a subtype of List<Number>, because a writable List<Number> could accept a Double. Wildcards describe the flexibility a method actually needs. ? extends Number lets it read numbers from several specific list types; ? super Integer lets it add integers to lists of Integer or a supertype.
How it works
The producer-extends, consumer-super guideline is often shortened to PECS. sum reads values as Number and calls doubleValue. addOne can insert Integer but cannot assume that values read back are Integer. This is a compile-time constraint, not a conversion of the underlying collection.
Common mistakes and limitations
An extends wildcard is not an immutable view: the API may still permit removal or clearing. You generally cannot add a non-null element through it because the precise element type is unknown. Avoid raw List types that bypass useful checks.
Try it and keep learning
Save the complete example below as Main.java. With a JDK supporting Java 17, compile using javac --release 17 Main.java, then run java Main from the same directory. These examples need only the standard library and fixed input; they do not require packages, files or network access.
Syntax
List<? extends Number> source; List<? super Integer> destination;Examples
Generic Wildcards: extends and super
Complete Main.java example — Java 17 or later, without preview features.
import java.util.ArrayList;
import java.util.List;
public class Main {
static double sum(List<? extends Number> values) {
double total = 0;
for (Number value : values) total += value.doubleValue();
return total;
}
static void addOne(List<? super Integer> values) { values.add(1); }
public static void main(String[] args) {
List<Integer> scores = List.of(2, 3);
List<Number> destination = new ArrayList<>();
addOne(destination);
System.out.println(sum(scores));
System.out.println(destination);
}
}- sum accepts List<Integer> because it only needs to read each value as a Number.
- doubleValue converts each value for addition and the resulting double prints as 5.0.
- addOne accepts List<Number>, which can safely store an Integer; the destination prints [1]. The method signatures describe the direction in which data moves.
- Expected output: 5.0 [1]
Best practices
- Use wildcards on parameters when they express the required flexibility.
- Keep a precise type when the method both consumes and produces the same element type.
Runtime & versions
Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Java Language Specification