Advanced Generics & Bounded Type Parameters
Prerequisites: Level 2 — Intermediate
A bounded type parameter restricts what a generic can be substituted with, so the compiler knows more about it — enough to call methods on it directly.
static <T extends Comparable<T>> T max(List<T> list) {
T result = list.get(0);
for (T item : list) {
if (item.compareTo(result) > 0) {
result = item;
}
}
return result;
}
Wildcards describe a generic whose exact type parameter doesn't matter, only its relationship to a bound:
static double sumAll(List<? extends Number> numbers) {
double total = 0;
for (Number n : numbers) {
total += n.doubleValue();
}
return total;
}
sumAll(List.of(1, 2, 3)); // works — List<Integer>
sumAll(List.of(1.5, 2.5)); // works — List<Double>
Common mistakes
- Using an unbounded
<T>and then trying to call a method (like.compareTo()) that only exists on some types — the compiler rejects it because plainTcould be anything.