Bounded and unbounded wildcards in Generics are two types of wildcard available on Java. Any Type can be bounded either upper or lower of the 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 wildcard in generics and what is an unbounded wildcard and then will some popular java interview questions on generics like Difference between ArrayList<? extends T> and ArrayList<T super ?>.
What are 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 the super class of T, here T represent the 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 provide 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 benefits of using bounded wildcard is that it not only restrict the number of Types can be passed to any method as an 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 have several examples of using bounded and unbounded wildcards in generics. Utility method provided in Collections class accepts parameterized arguments. Collections.unmodifiableSet(Set<? extends T> s) and Collections.unmodifiableMap(Map<? extends K,? extends V> m) are written using bounded wildcards which allow them to operate on either Collection of T or Collection of subclass or superclass 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 the super wildcard and when should you extends wildcards. Joshua Bloch in Effective Java book has suggested Producer extends, Consumer super mnemonic regarding the 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, it's worth reading the book for Java programmer. Anyway if type T is used as a producer than use <? extends T> and if type T represent consumer than use <? super T> bounded wildcards. Bounded wildcards in generics also increase the 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 subclass while other will accept T or super class. bounded wildcards give more flexibility to methods which can operate on a collection of T or its subclass. 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 subclass of T.
That's all on what is bounded wildcards in generics. both bounded and unbounded wildcards provide a lot of flexibility on API design especially because Generics is not covariant and List<String> can not be used in place of List<Object>. Bounded wildcards allow you to write methods which can operate on Collection of Type as well as Collection of Type subclasses.
Other Java articles you may like :