Generics
Type Bounds
Bounds constrain type parameters so your code can actually call methods on them:
<T extends Comparable<T>> promises order. Multiple bounds combine one class with any number of interfaces.<T extends Bound>— T must be a subtype of Bound (class or interface, "extends" covers both)- Multiple bounds:
<T extends Runnable & Comparable<T>>; the class (if any) comes first - Without a bound, T is implicitly
Object— only Object's methods are callable - The recursive form
<T extends Comparable<? super T>>is the production-grade signature
public static <T extends Comparable<T>> T min(T[] a) {
T smallest = a[0];
for (T x : a)
if (x.compareTo(smallest) < 0) smallest = x; // legal ONLY due to the bound
return smallest;
}Without extends Comparable<T>, the call x.compareTo(...) cannot compile — the compiler only knows T is an Object. The bound is both a restriction on callers and a capability inside the method.
The fully general form is <T extends Comparable<? super T>> — it accepts types whose superclass implements the comparison (e.g. java.sql.Timestamp extends java.util.Date, which implements Comparable<Date>). This "recursive type bound with a super wildcard" appears throughout java.util.Collections; the reasoning is pure PECS.