JavaGenerics

Type Bounds

Java type system ensures type restrictions, e.g.:

class Object {
    // We specify a method to return String, not Object
    public String toString();
}

Sometimes we want to apply the same restrictions to type parameters as well. When implementing a method that searches for a maximum of a collection we want to be sure that collection elements could be compared with each other, so the code below would not provide compile-time safety:

class Collections {

    public static <T> T max(Collection<T> coll) { ... }
}

Since max implementation will require casting to Comparable that may fail at runtime:

class Collections {

    public static <T> T max(Collection<T> coll) {
        ...
        T currentMax = coll.iterator().next();
        ...
        T currentElement = ...

        // Now we want to compare current element and current max
        ((Comparable<T>) currentMax).compareTo(currentElement); // this may fail at runtime!
    }
}

To restrict the type of elements to the ones implementing Comparable<T> type bounds could be used:

public static <T extends Comparable<T>> T max(Collection<T> coll) { ... }

This code may be future improved by applying the Get and Put principle to make method signature as general as possible to maximize utility:

public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll) { ... }

Type bound may have the form of single type variable:

<T extends Type> 

or class/interface type possibly followed by interface types:

<T extends Type & InterfaceType1 & InterfaceType2 & ... > 

Under the hood every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. So:

class SomeClass<T> { ... }

is equivalent to:

class SomeClass<T extends Object> {...}
How did you like the theory?
Report a typo