Adam Lally wrote: > On Mon, Aug 10, 2009 at 10:10 AM, Marshall Schor<m...@schor.com> wrote: > >> So, we're back to just the issue (unless another use case can be >> conceived) of how to iterate, where the uses of the iterator want to use >> methods from CASImpl. Is the concensus that having to cast here (e.g. >> Iterator<CAS> s = aCas.getViewIterator(); >> while (s.hasNext()) { >> CASImpl ci = (CASImpl) s.next(); >> ... code using ci... >> } >> is preferable to allowing the coder to to specify they want an iterator >> over <CASImpl> things, in this case? (Note that you can't fix this by >> writing: >> Iterator<CASImpl> s = (Iterator<CASImpl>)aCas.getViewIterator(); >> //gives error message cannot cast from Iterator<CAS> to Iterator<CASImpl> >> ) >> >> My preference would be for the form which permitted "Iterator<CASImpl> s >> = ...", because (a) it would make our code cleaner, (b) it's unlikely >> users would be confused by this. The amount of confusion to a user >> seems similar to the cases without generics, i.e. where a user could >> write a cast or assignment from a variable typed as a CAS to a CASImpl >> (which is of course permitted today). >> >> > > I actually think the code on top, with the explicit typecast, is > cleaner. The getViewIterator() guarantees only that it returns > objects of type CAS. If the caller expects those to be CASImpl, > relying on an internal undocumented invariant, then a typecast is a > perfectly appropriate way to do that. > > If a method's contract is that it returns an Iterator of objects of > type CAS, then it's logical that it's signature should say that it > returns Iterator<CAS>. What is wrong with that? If you change it to > return Iterator<T extends CAS>, I think you are saying that it can > return any subtype of CAS that the user may desire, which just isn't > true. > > Actually if anything I could see a case for the signature > Iterator<? super CAS> getViewIterator(); > > because this would allow > Iterator<AbstractCas> x = getViewIterator(); > >
True. However, it suffers from the same issue you discovered above. Iterator<CAS> s = aCas.getViewIterator(); // doesn't work, needs a cast: Iterator<CAS> s = (Iterator<CAS>) aCas.getViewIterator(); Same issue with using Iterator<AbstractCas> Two quick fixes: casting: Iterator<AbstractCas> s = (Iterator<AbstractCas>) aCas.getViewIterator(); and Iterator<? super CAS> s = aCas.getViewIterator(); -Marshall > -Adam > > >