Re: correct usage for @SuppressWarnings("unchecked")
Lew wrote:
'List <? extends List <String>>' and 'List <List <String>>'
are similar but different.
In both cases, all you can access for each element are 'List <String>'
behaviors.
In the former, while you don't know which implementation of 'List
<String>' each element is, you do know they're all the same kind. In the
latter, each element can be a different 'List <String>' implementation.
Daniel Pitts wrote:
In the former, you don't know they are all the same kind (List<String>
will match the wildcard just as well as ArrayList<String>).
Lew wrote:
I'm not sure I parsed your statement correctly, but the '?' wildcard
must evaluate to a specific type, which can be any subtype of 'List
<String>',
and that type, the "capture" of the wildcard, is the same for every
entry in
the 'List <? extends List <String>>'. That's what the semantics of the
wildcard requires.
Daniel Pitts wrote:
Basically, using <? extends List<String> means that the collection can
be of any type which extends List<String>, and you don't care, because
Lew wrote:
It also requires that all entries in the 'List <? extends List
<String>>' have the same type that is a subtype of 'List <String>'.
Daniel Pitts wrote:
you are only retrieving values from the collection, and you only care
about the functionality of List<String>
Lew wrote:
That is the part shared by both idioms.
Daniel Pitts wrote:
What I'm saying is List<? extends Foo> is assignable from List<Foo>, as
well as List<DerivedFromFoo>
So, you don't know that a List<? extends Foo> only includes one type,
since List<Foo> can include both Foo and DerivedFromFoo objects.
Yes, you do know that it only includes one type, in your example
either 'Foo' or 'DerivedFromFoo' depending on which list was assigned
to the variable. The capture will be the base type of the actual list
assigned. What you don't know from the point of view of the capturing
variable is which subtype of 'Foo' is in the list.
What you are saying is mostly correct, except for the "you don't know
that a List<? extends Foo> only includes one type" part since the
exact semantics of the wildcard is that you do know that it only
includes one type (or subtypes thereof, but those subtypes will not be
educeable).
To put it another way, all you can say with certainty about the types
of 'List <Foo>' elements is that they are all of type 'Foo'. Each
element may be of some different subtype of 'Foo'. In the case of
'List <? extends Foo>', you can aver that every element is of type
'Foo'. You can also aver that every element is of some unidentified
subtype of 'Foo', which may be 'Foo' itself or some proper subtype.
This is a rather subtle point and one that really doesn't come into
play until you try to match captures between different variables.
It is part of why it's an antipattern to return a wildcard base type
from a method, as in
List <? extends Foo> getList();
rather than the more manageable
List <Foo> getList();
You point up the other major difference, which is that
'List<DerivedFromFoo>'
is a subtype of
'List<? extends Foo>'
but not of
'List<Foo>'
..
The point of the ? extends is that you don't care what types it *could*
contain, as long as they are all assignable to a particular parent class.
That is the part shared by both idioms.
--
Lew