There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number
or its subclasses. This is what bounded type parameters are for.
To declare a bounded type parameter, list the type parameter's name, followed by the extends
keyword, followed by its upper bound, which in this example is Number
. Note that, in this context, extends
is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).
/** * This version introduces a bounded * type parameter. */ public class Box<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public <U extends Number> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); integerBox.add(new Integer(10)); // error: this is still String! integerBox.inspect("some text"); } }
By modifying our generic method to include this bounded type parameter, compilation will now fail, since our invocation of inspect
still includes a String
:
Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot be applied to (java.lang.String) integerBox.inspect("10"); ^ 1 error
To specify additional interfaces that must be implemented, use the &
character, as in:
<U extends Number & MyInterface>