What is the difference between List super T> and List extends T> ?
what is the difference between list<? super t> and list<? extends t> ?
extends
the wildcard declaration of list<? extends number> foo3
means that any of these are legal assignments:
list<? extends number> foo3 = new arraylist<number>(); // number "extends" number (in this context) list<? extends number> foo3 = new arraylist<integer>(); // integer extends number list<? extends number> foo3 = new arraylist<double>(); // double extends number
-
reading - given the above possible assignments, what type of object are you guaranteed to read from
list foo3
:- you can read a
number
because any of the lists that could be assigned tofoo3
contain anumber
or a subclass ofnumber
. - you can't read an
integer
becausefoo3
could be pointing at alist<double>
. - you can't read a
double
becausefoo3
could be pointing at alist<integer>
.
- you can read a
-
writing - given the above possible assignments, what type of object could you add to
list foo3
that would be legal for all the above possiblearraylist
assignments:- you can't add an
integer
becausefoo3
could be pointing at alist<double>
. - you can't add a
double
becausefoo3
could be pointing at alist<integer>
. - you can't add a
number
becausefoo3
could be pointing at alist<integer>
.
- you can't add an
you can't add any object to list<? extends t>
because you can't guarantee what kind of list
it is really pointing to, so you can't guarantee that the object is allowed in that list
. the only "guarantee" is that you can only read from it and you'll get a t
or subclass of t
.
super
now consider list <? super t>
.
the wildcard declaration of list<? super integer> foo3
means that any of these are legal assignments:
list<? super integer> foo3 = new arraylist<integer>(); // integer is a "superclass" of integer (in this context) list<? super integer> foo3 = new arraylist<number>(); // number is a superclass of integer list<? super integer> foo3 = new arraylist<object>(); // object is a superclass of integer
-
reading - given the above possible assignments, what type of object are you guaranteed to receive when you read from
list foo3
:- you aren't guaranteed an
integer
becausefoo3
could be pointing at alist<number>
orlist<object>
. - you aren't guaranteed a
number
becausefoo3
could be pointing at alist<object>
. - the only guarantee is that you will get an instance of an
object
or subclass ofobject
(but you don't know what subclass).
- you aren't guaranteed an
-
writing - given the above possible assignments, what type of object could you add to
list foo3
that would be legal for all the above possiblearraylist
assignments:- you can add an
integer
because aninteger
is allowed in any of above lists. - you can add an instance of a subclass of
integer
because an instance of a subclass ofinteger
is allowed in any of the above lists. - you can't add a
double
becausefoo3
could be pointing at anarraylist<integer>
. - you can't add a
number
becausefoo3
could be pointing at anarraylist<integer>
. - you can't add an
object
becausefoo3
could be pointing at anarraylist<integer>
.
- you can add an
pecs
remember pecs: "producer extends, consumer super".
-
"producer extends" - if you need a
list
to producet
values (you want to readt
s from the list), you need to declare it with? extends t
, e.g.list<? extends integer>
. but you cannot add to this list. -
"consumer super" - if you need a
list
to consumet
values (you want to writet
s into the list), you need to declare it with? super t
, e.g.list<? super integer>
. but there are no guarantees what type of object you may read from this list. -
if you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g.
list<integer>
.
example
note this example from the java generics faq. note how the source list src
(the producing list) uses extends
, and the destination list dest
(the consuming list) uses super
:
public class collections { public static <t> void copy(list<? super t> dest, list<? extends t> src) { for (int i = 0; i < src.size(); i++) dest.set(i, src.get(i)); } }
also see how can i add to list<? extends number> data structures?
reference:
https://*.com/questions/4343202/difference-between-super-t-and-extends-t-in-java
https://*.com/questions/2723397/what-is-pecs-producer-extends-consumer-super