I have a couple of questions about generic wildcards in Java:
What is the difference between
List<? extends T>
andList<? super T>
?What is a bounded wildcard and what is an unbounded wildcard?
I have a couple of questions about generic wildcards in Java:
What is the difference between List<? extends T>
and List<? super T>
?
What is a bounded wildcard and what is an unbounded wildcard?
If you have a class hierarchy A, B is a subclass of A, and C and D both are subclass of B like below
Then
A bounded wildcard is like
? extends B
where B is some type. That is, the type is unknown but a "bound" can be placed on it. In this case, it is bounded by some class, which is a subclass of B.Pre Requirements
The problem
listB = listA;
In listA you can insert objects that are either instances of A, or subclasses of A (B and C). Then you could risk thatlistA
contains non-B objects. When you then try to take objects out oflistB
you could risk to get non-B objects out (e.g. an A or a C). That breaks the contract of thelistB
variable declaration.listA = listB;
If you could make this assignment, it would be possible to insert A and C instances into the List pointed to bylistB
. You could do that via thelistA
reference, which is declared to be of List. Thus you could insert non-B objects into a list declared to hold B (or B subclass) instances.The purpose
You should use
List <? extends A>
(upper bound) if you are going to read .get() from the listYou should use
List <? super A>
(lower bound) if you are going to insert .add() into the listPlease read more here - http://tutorials.jenkov.com/java-generics/wildcards.html
In general,
To put elements into the structure we need another kind of wildcard called
Wildcards with super
,Josh Bloch also has a good explanation of when to use
super
andextends
in this google io video talk where he mentions the Producerextends
Consumersuper
mnemonic.From the presentation slides:
In your first question,
<? extends T>
and<? super T>
are examples of bounded wildcards. An unbounded wildcard looks like<?>
, and basically means<? extends Object>
. It loosely means the generic can be any type. A bounded wildcard (<? extends T>
or<? super T>
) places a restriction on the type by saying that it either has to extend a specific type (<? extends T>
is known as an upper bound), or has to be an ancestor of a specific type (<? super T>
is known as a lower bound).The Java Tutorials have some pretty good explanations of generics in the articles Wildcards and More Fun with Wildcards.
There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
means that it can accept all object who have IS- A relationship with MyObject (i.e. any object which is a type of myObject or we can say any object of any subclass of MyObject) or a object of MyObject class.
For example:
Then,
will accept only MyObject or children of MyObject(i.e. any object of type OurObject or YourObject or MyObject, but not any object of superclass of MyObject).