Bounds
In the process of discussing generics, we’ve already had to
mention bounds a few times. A bound is a constraint on the type of a type
parameter. Bounds use the extends keyword and some
new syntax to limit the parameter types that may be applied to a generic
type. In the case of a generic class, the bounds simply limit the type
that may be supplied to instantiate it.
A type variable may extend a class or interface type, meaning that its instantiation must be of that type or a subtype:
classEmployeeList<TextendsEmployee>{...}
Here, we made a generic EmployeeList type that can be instantiated only
with Employee types. We could further
require that the Employee type
implement one or more interfaces using the special & syntax:
classEmployeeList<TextendsEmployee&Ranked&Printable>{...}
The order of the & interface
bounds is not significant, but only one class type can be specified and if
there is one, it must come first. When a type has no specific bounds, the
bound extends Object is
implicit.
By applying bounds to our type, we not only limit the instantiations
of the generic class, but we make the type arguments more useful. Now that
we know that our type must extend some type or implement some set of
interfaces, we can use variables and arguments declared with T by those other type names. Here is a somewhat
contrived extension of our previous example:
classEmployeeList<TextendsEmployee&Ranked&Printable>{Rankedranking;List<Printable>printList=new ...