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
>
>
>   

Reply via email to