Java Wildcards
In this page:
What is a Wildcard?
In generic code, the question mark (?) is called a wildcard, and it represents an unknown type parameter rather than a fixed one. Wildcards let a single method signature accept collections of varied, related parameter types instead of locking callers into one exact type.
Example: What is a Wildcard?
import java.util.List;
public class Main {
static void printSize(List<?> list) {
System.out.println("Size: " + list.size());
}
public static void main(String[] args) {
printSize(List.of("a", "b", "c"));
printSize(List.of(1, 2));
}
}
Login to try C/C++/Java/PHP code in the editor
Unbounded Wildcards
An unbounded wildcard is written as a single question mark, like List<?>, and it represents any type parameter whatsoever. It's most useful for methods that only need to read from a collection's known Object-level API, such as printing its size, without caring what the elements actually are.
Example: Unbounded Wildcards
import java.util.List;
public class Main {
static void printAll(List<?> list) {
System.out.println("Items: " + list.size());
}
public static void main(String[] args) {
printAll(List.of(1, 2, 3));
}
}
Login to try C/C++/Java/PHP code in the editor
Upper Bounded Wildcards
An upper bounded wildcard restricts the type parameter to a specific class or its subclasses, written using the extends keyword, for example <? extends Number>. This lets a method safely read values out of the collection as that upper-bound type, since every possible element is guaranteed to be at least that type.
Example: Upper Bounded Wildcards
import java.util.List;
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) {
System.out.println(sum(List.of(1, 2, 3)));
}
}
Login to try C/C++/Java/PHP code in the editor
Lower Bounded Wildcards
A lower bounded wildcard restricts the type parameter to a specific class or its superclasses, written using the super keyword, for example <? super Integer>. This lets a method safely write values of that type into the collection, since any superclass container is guaranteed to be able to hold them.
Example: Lower Bounded Wildcards
import java.util.List;
import java.util.ArrayList;
public class Main {
static void addNumbers(List<? super Integer> list) {
list.add(10);
list.add(20);
}
public static void main(String[] args) {
List<Number> numbers = new ArrayList<>();
addNumbers(numbers);
System.out.println(numbers);
}
}
Login to try C/C++/Java/PHP code in the editor
Wildcard Guidelines (PECS)
The PECS mnemonic sums up when to use each: Producer Extends, Consumer Super. Use an extends wildcard when a collection only produces values you're reading out of it, and a super wildcard when a collection only consumes values you're putting into it.
Example: Wildcard Guidelines (PECS)
import java.util.List;
public class Main {
static double sum(List<? extends Number> producer) { // Producer Extends
double total = 0;
for (Number n : producer) total += n.doubleValue();
return total;
}
static void fill(List<? super Integer> consumer) { // Consumer Super
consumer.add(1);
}
public static void main(String[] args) {
System.out.println(sum(List.of(1, 2, 3)));
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: