Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!gandalf.srv.welterde.de!feeder.erje.net!news-1.dfn.de!news.dfn.de!news.informatik.hu-berlin.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: blmblm@myrealbox.com Newsgroups: comp.lang.java.programmer Subject: Re: generics puzzle Date: 18 Oct 2011 14:49:51 GMT Organization: None Lines: 115 Message-ID: <9g5i0eFnnbU2@mid.individual.net> References: <9g2f24Fi0vU1@mid.individual.net> <45bfae98-a142-469b-9b8b-9aa8a59391f1@n13g2000vbv.googlegroups.com> X-Trace: individual.net q7A+Co5vIhzZOqVEKsl7LAVXjF/2ODJnu9Kdz2gJBqwZdHD7qa X-Orig-Path: not-for-mail Cancel-Lock: sha1:OyXocXBVBF+d+uwgSig24i866I8= X-Newsreader: trn 4.0-test76 (Apr 2, 2001) Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:8953 In article <45bfae98-a142-469b-9b8b-9aa8a59391f1@n13g2000vbv.googlegroups.com>, Robert Klemme wrote: > On Oct 17, 12:41 pm, blm...@myrealbox.com > wrote: > > I'm having a bit of trouble with generics, and while I've come > > up with ways of getting done what I want to get done, I wonder > > whether there's some nice solution that isn't occurring to me. > > > > The basic situation is this: > > > > I have an abstract generic class (call it GThing) with type > > parameter T, which has a method (call it set()) that takes a > > parameter of type T and another method (call it modified()) that > > returns a result of type T. I also have some classes that extend > > GThing and specify its type parameter, and code that is meant > > to operate on lists of instances of these various subclasses. > > What I would *like* to be able to do is construct a list of > > GThing objects and then do to each element of it something > > like the following: > > > > element.set(element.modified()) > > > > but the compiler objects to that, which I find reasonable enough, > > though I'm not enough of a generics expert to really articulate > > what the problem is. (I have a feeling that this "type erasure" > > thing, which I understand dimly at best, comes into it. :-)? ) > > The reason is the ? in the type: the compiler does not know the type. > The very moment you declare a List> the type of T is unknown > even though it's the same instance. Unknown types cannot be > compatible yet you try to do invoke a method with argument type ? with > a parameter of type ? and since "? incompatible to ?" it is not > allowed. Nice job of putting into words my vague idea about what's wrong; thanks! > You are basically doing this (list1) but bounding does not help > (neither way, list2 and list3); only concrete types are able to ensure > type compatibility: > > import java.util.ArrayList; > import java.util.List; > > public class GenericsProblemRK { > > public static void main(String[] args) { > final List> list1 = new ArrayList>(); > > for (final List l : list1) { > l.add(l.get(0)); // error > final Object x = l.get(0); // OK > l.add(x); // error > } > > final List> list2 = new ArrayList extends String>>(); > > for (final List l : list2) { > l.add(l.get(0)); // error > final Object x = l.get(0); // OK > l.add(x); // error > } > > final List> list3 = new ArrayList String>>(); > > for (final List l : list3) { > l.add(l.get(0)); // error > final Object x = l.get(0); // OK > l.add(x); // error > } > > final List> list4 = new ArrayList>(); > > for (final List l : list4) { > l.add(l.get(0)); // OK > } > } > > } > > > One fix is to just introduce a method setFromModified() in GThing, > > but that doesn't appeal to me. An ugly-hack fix is to add to > > GThing a set() method that takes an Object and typecasts it, > > but -- yuck, right? > > In your case since apparently you want to update internally why not > just introduce > > public void update() { > set(modified()); > } I'm not sure I can say why this doesn't appeal to me -- something about not wanting to clutter up GThing with unnecessary methods. > This will safely compile. Basically this is what you did with > setModified() in the wrapper class. All other approaches will be > hacky (i.e. involve explicit casting, using Object parameters or > return values etc.). Yeah, maybe .... In my "real" code (quotation marks because it's a toy project embarked on for entertainment and a bit of education) the method in the wrapper class does more than just call modified() and then set(). I don't know that that matters much, though. I do have a couple of different "call sites" (to use another poster's term) that need similar functionality, so maybe it *does* go in GThing. Well, like I said, "entertainment and a bit of education", and for me that seems to involve -- the coding equivalent of periodically rearranging the furniture, maybe. -- B. L. Massingill ObDisclaimer: I don't speak for my employers; they return the favor.