Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2006

Tip: Looking for answers? Try searching our database.

unchecked conversion problem

Thread view: 
rschmid-google@raptor.net - 25 Oct 2006 20:05 GMT
I have finally been allowed to upgrade to Java5 and I just finished
fixing some 1200 parameterization warnings which has really improved
the code.  I have one, ONE, left and I'm not sure it can be fixed.

I have the following object heierarchy;

SourceMatch
CMatch extends SourceMatch
DMatch extends SourceMatch

SMatchService<T extends SourceMatch>
CMatchService extends SMatchService<CMatch>
DMatchService extends SMatchService<DMatch>

in SMatchService is the following method

public abstract List<T> getMatchingSources(args) {}

which is implemented in the subclass services thus;

public List<CMatch> getMatchingSources(args) {}

and

public List<DMatch> getMatchingSources(args) {}

yet the following code throws an unchecked conversion warning;

SMatchService sourceMatchService = null;
if (c) sourceMatchService = new CMatchService();
else if (d) sourceMatchService = new DMatchService();

List<SourceMatch> sourceList =  =
sourceMatchService.getMatchingSources(args);

I have tried using wildcard parameters but my understanding is
imperfect at best.

I suspect that the problem is really architectural but I wanted to find
out if there is a way to make this work.

Any help is appreciated.
Niklas Matthies - 25 Oct 2006 20:20 GMT
> yet the following code throws an unchecked conversion warning;
>
[quoted text clipped - 4 lines]
> List<SourceMatch> sourceList =  =
> sourceMatchService.getMatchingSources(args);

Try this:

  SMatchService<?> sourceMatchService = null;
  if (c) sourceMatchService = new CMatchService();
  else if (d) sourceMatchService = new DMatchService();

  List<? extends SourceMatch> sourceList =
     sourceMatchService.getMatchingSources(args);

-- Niklas Matthies
rschmid-google@raptor.net - 25 Oct 2006 22:18 GMT
> > yet the following code throws an unchecked conversion warning;
> >
[quoted text clipped - 15 lines]
>
> -- Niklas Matthies

Great! Except now;

sourceList = new ArrayList<SourceMatch>();
sourceList.add(new SourceMatch());

throws an error.

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?
Niklas Matthies - 26 Oct 2006 00:00 GMT
>>    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
Lasse Reichstein Nielsen - 26 Oct 2006 00:13 GMT
>>    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.
Lasse Reichstein Nielsen - 25 Oct 2006 21:53 GMT
> yet the following code throws an unchecked conversion warning;
>
> SMatchService sourceMatchService = null;

Here SMatchService lacks a type parameter. Try:
SMatchService<? extends SourceMatch> sourceMatchService = null;

> if (c) sourceMatchService = new CMatchService();
> else if (d) sourceMatchService = new DMatchService();
>
> List<SourceMatch> sourceList =  =
> sourceMatchService.getMatchingSources(args);

And here the list you get will be:
 List<? extends SourceMatch> sourceList =
   sourceMatchService.getMatchingSources(args);

/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.'



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.