Adam Lally wrote: > On Sat, Aug 8, 2009 at 4:57 PM, Marshall Schor<m...@schor.com> wrote: > >> Jörn Kottmann wrote: >> >>> On Aug 7, 2009, at 8:57 PM, Marshall Schor wrote: >>> >>> >>>> getViewIterator in CASImpl is written with the signature: >>>> Iterator<CAS> getViewIterator() >>>> >>>> If you are working with things needing CASImpl objects, you would write: >>>> >>>> Iterator<CAS> s = aCas.getViewIterator(); >>>> while (s.hasNext()) { >>>> CASImpl ci = (CASImpl) s.next(); >>>> ... code using ci... >>>> } >>>> >>>> If we changed the signature to: >>>> Iterator<T extends CAS> getViewIterator() >>>> then you would write: >>>> Iterator<CASImpl> s = aCas.getViewIterator(); // cast done inside the >>>> support code, not here >>>> while (s.hasNext()) { >>>> CASImpl ci = s.next(); // works OK without casting >>>> ... code using ci... >>>> } >>>> >>>> Would it be better to have that form of the signature? >>>> >>> +1, though did not know that its possible, we should check other >>> places too >>> >> +1 to checking other places :-) >> >> The tutorial on generics by Gilad Bracha, >> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf, on page 20 near >> the top says: >> >> >>> In general, if you have an API that only uses a type parameter T as an >>> argument, its >>> uses should take advantage of lower bounded wildcards (? super T). >>> Conversely, if >>> the API only returns T, you’ll give your clients more flexibility by >>> using upper bounded >>> wildcards (? extends T). >>> >> There are many cases I think in our generification where the 2nd part of >> this, returning XXX<? extends T> or a variant, is a better choice. >> >> > > I must say I don't understand why returning something like List<? > extends CAS> is an improvement. Is this supposed to mean that the > client could specify ANY subtype of CAS and it's supposed to work? So > someone could write: > class MyCas implements CAS {...} > List<MyCas> result = aCAS.getViewIterator() > Which couldn't possibly work. I guess it would compile but generate a > ClassCastException at runtime. Is that a good thing? > > I found an expert with a differing point of view from your expert: > http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU > > "Keep bounded wildcards out of return values > > It is sometimes tempting to use a bounded wildcard in the return type > of a method. But this temptation is best avoided because returning > bounded wildcards tends to "pollute" client code. If a method were to > return a Box<? extends T>, then the type of the variable receiving the > return value would have to be Box<? extends T>, which pushes the > burden of dealing with bounded wildcards on your callers. Bounded > wildcards work best when they are used in APIs, not in client code." >
This is a good discussion. I didn't realize that about bounded wildcards. But there's another choice. Consider the difference between <? extends T> and a form that looks like: public <T extends AbstractCas> Iterator<T> getViewIterator() { This latter form doesn't use a wild card, and if it is used as the return type of the method, the return type's match for T gets used, and this doesn't have the issue above. So that's another choice, and that was the choice I was thinking about in my original post, where the actual form was written incorrectly (the correct way is above). Here's another (probably weak) use case for returning <T extends AbstractCas> kinds of things: If you have part of the code which collects views and some of these views use one form of the AbstractCas (e.g. CASImpl) and others use the JCas form, it would be nice to be able to put these two uses into a collection (of AbstractCas) - which is the kind of thing AbstractCas was trying to do, I believe. If we changed getViewIterator to return Iterator<AbstractCas> (another choice), that would serve the use case in the above paragraph, but then the form Iterator<CAS> it = aCas.getViewIterator() would give a compile-time error. It seems to me that <T extends AbstractCas> is a better generification, here. -Marshall > -Adam > > >