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();

 -Adam

Reply via email to