Bounded and un-bounded wildcards in Generics are two types of wildcard available on Java. Any Type can be bounded either upper or lower of class hierarchy in Generics by using bounded wildcards. In short <? extends T> and <? super T> represent bounded wildcards while <?> represent an unbounded wildcard in generics . In our last article How Generics works in Java , we have seen some basic details about bounded and unbounded wildcards in generics and In this Java tutorial we will see bounded and unbounded generics wildcards in details. We will start from basics like what is bounded wild card in generics and what is unbounded wildcard and than will some popular java interview questions on generics like Difference between ArrayList<? extends T> and ArrayList<T super ?>.
What is bounded and unbounded wildcards in Generics
bounded and unbounded wildcards in generics are used to bound any Type. Type can be upper bounded by using <? extends T> where all Types must be sub-class of T or lower bounded using <? super T> where all Types required to be super class of T, here T represent lower bound. Single <?> is called an unbounded wildcard in generic and it can represent any type, similar to Object in Java. For example List<?> can represent any List e.g. List<String> or List<Integer> its provides highest level of flexibility on passing method argument.
On the other hand bounded wildcards provides limited flexibility within bound. Any Type with bounded wildcards can only be instantiated within bound and any instantiation outside bound will result in compiler error.One of the important benefit of using bounded wildcard is that it not only restrict number of Type can be passed to any method as argument it also provides access to methods declared by bound. for example TreeMap(Comparator<? super K> comparator) allows access to compare() method of Comparator in Java.
Example of Bounded and Unbounded wildcards in Java Generics:
Java Collection frameworks has several examples of using bounded and unbounded wildcards in generics. Utility method provided in Collections class accepts parametrized arguments. Collections.unmodifiableSet(Set<? extends T> s) and Collections.unmodifiableMap(Map<? extends K,? extends V> m) are written using bounded wildcards which allows them to operate on either Collection of T or Collection of sub class or super class of T. just look at Java API for 1.5 and you will find lot of example of bounded and unbounded generic wildcards within JDK itself. If you are learning Java 1.5 you can also check my post on Java Enum and Variable arguments in Java.
When to use super and extends wildcards in Generics Java
Since there are two kinds of bounded wildcards in generics, super and extends, When should you use super wildcard and when should you extends wildcards. Joshua Bloach in Effective Java book has suggested Producer extends, Consumer super mnemonic regarding use of bounded wildcards. This book also has some good advice regarding how to use generics in Java and if you haven’t read it already, its worth reading book for Java programmer. Any way if type T is used as producer than use <? extends T> and if type T represent consumer than use <? super T> bounded wildcards. Bounded wildcards in generics also increase flexibility of any API. To me its question of requirement, if a method also needs to accept any implementation of T then use extends wildcards.
Difference between ArrayList<? extends T> and ArrayList<? super T>
This is one of popular generics interview question , which is asked to check whether you are familiar to bounded wildcards in generics. both <? extends T> and <? super T> represent bounded wildcards, one will accept only T or sub class while other will accept T or super class. bounded wildcards gives more flexibility to methods which can operate on collection of T or its sub class. If you look at java.util.Collections class you will find several example of bounded wildcards in generics method. e.g. Collections.unmodifiableSet(Set<? extends T> s) will accept Set of type T or Set of sub class of T.
That's all on what is bounded wildcards in generics. both bounded and unbounded wild cards provides lot of flexibility on API design specially because Generics is not co-variant and List<String> can not be used in place of List<Object>. Bounded wildcards allows you to write methods which can operate on Collection of Type as well as Collection of Type subclasses.
Other Java articles you may like :