Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<? super E> and <? extends E> for List

Tags:

java

generics

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?

like image 946
qbaquak Avatar asked Dec 15 '09 11:12

qbaquak


People also ask

What is extend E Java?

extends E> means any object including E that is child of E .

What is the difference between Super and extends?

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 .

What does list extend in Java?

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.

What is difference between extends and super in Java?

super is a lower bound, and extends is an upper bound.


2 Answers

"? 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.

like image 106
Jon Skeet Avatar answered Sep 23 '22 09:09

Jon Skeet


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.

like image 32
Steve De Caux Avatar answered Sep 23 '22 09:09

Steve De Caux