Basically you need to decide, more importantly, to be general in comparison with what you want to put in the wrapper, on top of or what you take out of the wrapper (you cannot safely both). After making the decision, you will need to choose between extends
and super
.
If you just want to keep the pointer, then List<Wrapper<Wrapper>>
will be enough, but then you will need to do some casting later.
When you use extends
, then ? extends Foo
? extends Foo
means that any data type returned by the structure will be a subtype of type Foo
(or Foo
).
For example, if you have void doIt1( List< ? extends Mammal> l ){}
, you can pass List<Human>
, List<Primate>
, List<Simian>
or List<Mammal>
.
However, when using ? extends
? extends
you donβt know what you can safely insert.
Consider this:
void addElephant( List< ? extends Mammal> l ){ l.add( new Elephant() );
This is clearly unsafe ! I could go to List<Human>
as l
, and now my Human
list has an Elephant
in it!
On the other hand, you have super
, where ? super Foo
? super Foo
means the container can accept Foo
.
So, for void doIt2( List< ? extends Human> l ){}
, how could you go to List<Human>
, List<Primate>
, List<Simian>
, List<Mammal>
or List<Object>
.
void ( List< ? super Human> l ){ l.add( new Human() ); }
And that's fine, but you canβt guarantee anything about what you choose from the container.
void ( List< ? super Human> l ){ Human h = l.get(0);
This is because if l
really was a List<Primate>
, it could have a mixture of Human
and Gorilla
, and there is no guarantee that the first element will be Human
.
To do this, you will get the abbreviation PECS
= "[a] P roducer ** E xtends, [but a] C onsumer S.
If you the container returns the object to the method (for example, get
), then you are a "production" (therefore use extends
), otherwise, if you take elements (for example, add
) to the container, the container "consumes" the object, so use " super". ( Nb :) , to remember PECS, it is that it is from the point of view of the container, not the calling code!).
If you want to produce and consume, you will need to have a specific list of List<Primate>
types, where you can add Human
and get Primate
s.
See also: