Bounded Type Parameters
TL;DR
- Bounded Type Parameters restrict the types that can be used as generic arguments.
- You use the
extendskeyword to define an Upper Bound. - Syntax:
<T extends SuperClass>. This meansTcan beSuperClassor any of its subclasses.
Concept
Sometimes you want a generic type T, but you don’t want it to be any object; you want to ensure it has certain capabilities.
For example, if you write a generic method to calculate the average of an array of numbers, you need to ensure that T is a numeric type (so you can call .doubleValue() on it). By defining <T extends Number>, you guarantee that T is either Number, Integer, Double, etc.
You can also bound by an interface. In Generics, you still use the keyword extends, even if you are bounding to an interface (e.g., <T extends Comparable<T>>).
Examples
// 1. Class-level bounding
class MathBox<T extends Number> {
private T number;
public MathBox(T number) { this.number = number; }
public double getDoubleValue() {
// Safe to call doubleValue() because T is guaranteed to be a Number
return number.doubleValue();
}
}
public class BoundsExample {
// 2. Method-level bounding (Multiple Bounds)
// T must implement both Comparable AND Serializable
public static <T extends Comparable<T> & java.io.Serializable> void process(T item) {
System.out.println("Processing: " + item);
}
public static void main(String[] args) {
MathBox<Integer> intBox = new MathBox<>(10);
MathBox<Double> doubleBox = new MathBox<>(10.5);
// MathBox<String> stringBox = new MathBox<>("Hi"); // COMPILE ERROR!
process("Hello"); // String implements Comparable and Serializable
}
}
Interview Questions
Q: Can you use super keyword to define a lower bound for a class type parameter (e.g. class Box<T super Integer>)?
A: No. You cannot use the super keyword to define a lower bound in a class or method declaration. super can only be used with Wildcards (e.g., List<? super Integer>) when using a generic type.
Q: How do you specify multiple bounds for a generic type?
A: You can use the & symbol to specify multiple bounds: <T extends ClassA & InterfaceB & InterfaceC>. Note that because Java does not support multiple inheritance for classes, T can only extend a maximum of one Class, and that Class must be listed first, followed by any number of Interfaces.