Bounded and unbounded wildcards in Generics are two types of wildcards 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 detail.
We will start from basics like what is a 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 ?>.
We will start from basics like what is a 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> it provides the highest level of flexibility on passing method argument.
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> it provides the 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 a compiler error.
One of the important benefits of using a bounded wildcard is that it not only restricts the number of Types that 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. The 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 extend 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 programmers.
Anyway if type T is used as a producer then use <? extends T> and if type T represents consumer then use <? super T> bounded wildcards. Bounded wildcards in generics also increase the flexibility of any API. To me, it's a 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 the popular generics interview questions, 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 the other will accept T or superclass.
bounded wildcards give more flexibility to methods that can operate on a collection of T or its subclass. If you look at java.util.Collections class you will find several examples of bounded wildcards in the 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 that can operate on Collection of Type as well as Collection of Type subclasses.
Other Java articles you may like :
11 comments :
Generic's Bounded wildcards if used as method arguments definitely increase flexibility of code. formal parameters which accept Bounded argument are like coding for interface than implementation.
A little typo in first paragraph: "and than will some popular" , it should be " then will some popular".
I have seen than/then issue somewhere else in your articles.
Your articles are fantastic by the way and I suggest you should write a book.In short , thank-you for the posts :)
Bounded wildcards used as method parameters, impose that the collection will not be modifiable within the method.
only explainations ? well, that's not enough, u should provide some simple codes....
The theory is corectly explained but the examples are very poor...
Explanation was not up to mark . It could have been better..
Hello @Gyanesh, please tell me what is shortcoming and how it can be improved?
Well, I can answer why your examples of wildcards are poor.
Let's say, you have :
List list = new ArrayList<>();
list.add(new Object());
Could you explain, why this does not compile?
There are a lot of other things you might have told about wildcards. Right now, this tutorial does not have any value. Sorry.
@Javin .Good explanation but can you provide some code example for better understanding.
Thanks
Anonymous said...
Well, I can answer why your examples of wildcards are poor.
Let's say, you have :
List list = new ArrayList<>();
list.add(new Object());
Could you explain, why this does not compile?
may be your compiler is outdated......or else you could just upload the error you got.
the answer which i got when i compiled and executed is...
List list = new ArrayList<>();
list.add(new Object());
System.out.println(list); // answer will be like [java.lang.Object@e73f9ac]
Bad Explanation
Post a Comment