We’ve seen how generics make our code scalable by allowing us to provide type arguments to classes, interfaces, and methods. What if we needed to restrict what class or interface could be used as a type argument? We can accomplish this by assigning an upper bound. An upper bound will limit the type parameter to a parent type or any of its child types. Let’s see how this is done:
public class Box <T extends Number> { private T data; }
In the example above we defined type parameter T
. We added an upper bound type Number
for T
with extends Number
. The extends
in this example means that T
can be a Number
or any of its child classes (or interfaces).
We can create references to Box as follows:
Box<Integer> intBox = new Box<>(2); // Valid type argument Box<Double> doubleBox = new Box<>(2.5); // Valid type argument Box<String> stringBox = new Box<>("hello"); // Error
In the example above we’ve:
- Created two
Box
references with type argumentsInteger
andDouble
, which are both child classes ofNumber
. - Attempted to create a
Box
reference with type argumentString
and receive an error becauseString
is not aNumber
type or any of its child classes.
We can similarly add upper bounds to generic methods as follows:
public static <T extends Number> boolean isZero(T data) { return data.equals(0); }
In the example above, it’s important to note that we added the Number
upper bound prior to the return type.
Java also allows us to create a type parameter with multiple bounds. Let’s look at an example:
public class Box <T extends Number & Comparable<T>> { private T data; }
In the example above, we specify multiple bounds (Number
and Comparable
) for type parameter T
using the &
operator between the different upper bounds. It’s important to note that when defining multiple bounds, any upper bound that is a class
, in our example Number
, must come first followed by any interfaces, in our example Comparable<T>
.
Let’s practice adding an upper bound to a generic class.
Instructions
Currently the our class Bus
can have any type of generic parameter which we’d like to restrict down to better meet our needs.
In Box.java, modify the type parameter so that we can only create “Boxes” of SchoolPerson
, Student
, or Teacher
.
Note: Feel free to look at SchoolPerson.java, Student.java, and Teacher.java to see how they relate to each other.