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

Reply via email to