>> List<? extends SourceMatch> sourceList =
>> sourceMatchService.getMatchingSources(args);
[quoted text clipped - 8 lines]
> I can work around this by creating a new list and copying one into
> the other but that is wasteful. What's the right syntax?
You need to use a second variable declared with a different type:
List<SourceMatch> sourceList2 = new ArrayList<SourceMatch>();
sourceList2.add(new SourceMatch());
List<SourceMatch> means that the list can contain _any_ instances
of SourceMath. List<? extends SourceMatch> on the other hand means
that the list can contain only instances of _some specific_ (but
unspecified) subtype of SourceMatch. The '?' might actually be
SourceMatch itself, but it also might be CMatch or DMatch. That's
why the compiler doesn't allow you to add an arbitrary SourceMatch
instance to such a list, because the list could for example really be
a List<CMatch>, to which it's only permissible to add CMatch objects.
Consider:
List<CMatch> cList = new ArrayList<CMatch>();
List<? extends SourceMatch> sourceList = cList; // fine
sourceList.add(new SourceMatch()); // (*)
// oops, now cList contains a SourceMatch object although
// it is a List<CMatch>!
CMatch cMatch = cList.get(i); // throws ClassCastException!
That's why the line (*) is rejected by the typechecker.
To get a better understanding of generics I suggest you take a look
at http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html .
-- Niklas Matthies
>> List<? extends SourceMatch> sourceList =
>> sourceMatchService.getMatchingSources(args);
[quoted text clipped - 5 lines]
>
> throws an error.
As it should. ArrayList<SourceMatch> is not assignable to
List<? extends SourceMatch>.
You can do
sourceList = new ArrayList<? extends SourceMatch>();
but you can't add a SourceMatch to that (or anything at all).
Remember, a List<SourceMatch> and a List<CMatch> are not assignable
to each other. The former allows you to put SourceMatch'es into it,
the latter doesn't. And the latter guarantees that what you take
out of it is a CMatch, the former doesn't.
If you want a variable to hold both of the above list types, it
needs to be something like List<? extends SourceMatch> (which is
a supertype of both). However, you cannot add elements to that list,
since it might be both a List<CMatch> or a List<DMatch>, which cannot
contain the same elements.
Instead, you could just let the getMatchingSources return a
List<SourceMatch>.
/L

Signature
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
rschmid-google@raptor.net - 26 Oct 2006 16:07 GMT
> >> List<? extends SourceMatch> sourceList =
> >> sourceMatchService.getMatchingSources(args);
[quoted text clipped - 23 lines]
> since it might be both a List<CMatch> or a List<DMatch>, which cannot
> contain the same elements.
Ah, Thank you! That was the point I had forgotten. Once I understood
it became obvious that I could move the actual code into a new
parameterized method in SourceMatch.