Adam Lally wrote: > On Mon, Aug 10, 2009 at 12:28 PM, Marshall Schor<m...@schor.com> wrote: > >> Adam Lally wrote: >> >>>> Same issue with using Iterator<AbstractCas> >>>> Two quick fixes: casting: >>>> Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator(); >>>> and >>>> Iterator<? super CAS> s = aCas.getViewIterator(); >>>> >>>> >>>> >>> Right.. I think it needs to be like this: >>> >>> <T extends Iterator<? super CAS>> T getViewIterator() >>> >>> >> I tried this, and get for : >> Iterator<CAS> s = aCas.getViewIterator(); >> the message: Bound mismatch: The generic method getViewIterator() of >> type CAS is not applicable for the arguments (). The inferred type CAS >> is not a valid substitute for the bounded parameter <T extends >> Iterator<? super CAS>> >> and no quick fixes. >> >> I tried some variants, but couldn't get something that worked... >> >> > > Well, the following test compiles for me, but I realized that the > solution isn't good anyway because even though the code can compile > with a dummy method implementation, I can't actuall provide a real > implementation for the method! > > public class Test { > public static void main(String[] args) throws Exception { > List<AbstractCas> x = getViewIterator(); > List<CAS> y = getViewIterator(); > > } > > private static <T extends List<? super CAS>> T getViewIterator() { > T result = null; > CAS c = null; > result.add(c); > return result; > } > > > On the line "T result = null" I can't instantiate T to an actual list > (I'd have to instantiate whatever type T the client requested, and > there's no guarantee that's even possible to do.) > > So, bottom line, I say we stick with the recommendation of Brian > Goetz's article and don't use wildcards in return types. >
Sounds right. But we should use bounded wildcards for "arguments" where appropriate (of course, this doesn't apply to getViewIterator, which has no arguments). The article, http://www.ibm.com/developerworks/java/library/j-jtp07018.html?S_TACT=105AGX02&S_CMP=EDU has a nice "principle" called the "get-put" principle for arguments: Use an |extends| wildcard when you only get values out of a structure, use a |super| wildcard when you only put values into a structure, and don't use a wildcard when you do both. For the last part, he also says the reason for not using a wild card if you do both: If you can put a |T| or any of its subtypes, and you can get a |T| or any of its supertypes, then the only thing you can both get and put is a |T| itself. -Marshall > -Adam > > >