Java Generics: Lower and Upper Bound

Tudip Technologies

24 June, 2016

In generics ? (called as unbounded wildcard) is used to accept just any type of object.
However, we can restrict this behaviour by applying a Lower-Bound or Upper-Bound to wildcard ?.
Upper-bound is when you specify (? extends Field) means argument can be any Field or subclass of Field.
Lower-bound is when you specify (? super Field) means argument can be any Field or superclass of Field.
Try following code: Uncomment the code and check if any error comes.
import java.util.ArrayList;
import java.util.Collection;

public class GenericsDemo {

    public static void validateTillStringType(Collection<? super String> collection){
        //Wild card with Lower bound
        // Accept collection of objects of type string or SUPER-CLASS of String
    }

    public static void validateStringTypes(Collection<? extends String> collection){
        //Wild card with Upper bound
        // Accept collection of objects of type string or SUB-CLASS of String
    }

    public static void main(String [] args){      
        GenericsDemo.validateTillStringType(new ArrayList<Object>());//OK

//      GenericsDemo.validateTillStringType(new ArrayList<Integer>());//Error

//      GenericsDemo.validateStringTypes(new ArrayList<Object>());//Error

        GenericsDemo.validateStringTypes(new ArrayList<String>());//OK

    }

}

We can also apply bounds to type variables as one parameter will depend on other parameter.
A type variable ( usually T) is option for wildcard ?. Both of following two method signatures are equivalent to each other.

    public static void validateTillStringType(Collection<?> collection){ }
    public static <T> void validateTillStringType(Collection<T> collection){ }

Note that type variable T is declared immediately before return type, but it does not relate to return type in any way.

How to put bounds for type variable?

Suppose we have a method to copy elements at a destination from a given source. In this case we need to make sure that the source elements are compatible with destination elements. A.K.A. source element type extends destination element type, method would look like:

     public static <T> void copy(List<T> dest, List<? extends T> src) { }

In above method we use a type variable T. With help of this declared T, we are able to apply an upper bound to wildcard of src.
If we want to avoid the wildcard, we can declare one more type variable for second argument and apply bound in declaration place. Above method can be declared in new style as:

     public static <T,V extends T> void copy(List<T> dest, List<V> src) { }

You can find more reference at : http://docs.oracle.com/javase/tutorial/extra/generics/index.html
For more information please refer this tutorial : http://docs.oracle.com/javase/tutorial/extra/generics/methods.html