Having the following simple class structure:
class A {
}
class B extends A {
}
class C extends B {
}
I'm creating an ArrayList to keep objects of the earlier created classes:
List<? extends A> list1 = new ArrayList<A>();
List<? extends B> list2 = new ArrayList<B>();
List<? extends C> list3 = new ArrayList<C>();
List<? super A> list4 = new ArrayList<A>();
List<? super B> list5 = new ArrayList<B>();
List<? super C> list6 = new ArrayList<C>();
To each of those lists I'm trying to add 1 object of each earlier created class: A,B,C. The only possible combination is:
adding object of class A,B,C to list4
adding object of class B and C to list5
adding object of class C to list list6. The rest of the tries gives compiler errors, such us:
The method add(capture#1-of ? extends A) in the type List is not applicable for the arguments (A)
Why can't I add any object of class A,B,C to list1/2/3? Why e.g. list4 accepts objects of classes A,B,C if they are supposed to be a super class of class A, as the list4 is defined?
extends E> means any object including E that is child of E .
Producer – If you want to only retrieve the elements from a generic collection, use extends . Consumer – If you want to only put elements into a generic collection, use super . If you do both retrieve and put operations with the same collection, you shouldn't use either extends or super .
extends Number> p ,it means you can use anything extends Number to fill the ArrayList. 2)Lower Bounded Wildcards. like: ArrayList<? super Integer> list , it means you have to pass anything who is the super class (such as Number,Object)of Integer to fill the ArrayList.
super is a lower bound, and extends is an upper bound.
"? extends A" means "some type derived from A (or A itself)". So for instance, a List<ByteArrayOutputStream>
is compatible with List<? extends OutputStream>
- but you shouldn't be able to add a FileOutputStream
to such a list - it's meant to be a List<ByteArrayOutputStream>
! All you know is that anything you fetch from the list will be an OutputStream
of some kind.
"? super A" means "some type which is a superclass of A (or A itself)". So for instance, a List<OutputStream>
is compatible with List<? super ByteArrayOutputStream>
. You can definitely add a ByteArrayOutputStream
to such a list - but if you fetch an item from the list, you can't really guarantee much about it.
See Angelika Langer's Generics FAQ for much more information.
The type definition List<? extends A>
is not usable for a mutable List - the explanation given in Java generics Java Generics Pdf is
The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don’t know what type that is, we cannot pass anything in.
However, when the typedef is List<? super A>
then the type parameter ? is implicitly typed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With