Adrian,
I am now understanding what your doubts are (in fact I am not sure any more about my previous answer: it does not look correct).
As you said, this is correct:
Originally posted by Adrian Sosialuk:
then you can pass call it for example:
In fact (the same outside an static context):
It is correct too.
However, the example in Angelica's Lange FAQ is still giving trouble.
I tried modifiying the code a bit to this:
As you can see this version of the example uses Integer and Number as types instead of U and
? super U.
The compiler gives the following error:
This message looks very similar to the one given for the original version of the code.
The problem looks more evident now:
- our ConcreteAcceptor is of type Number
- accept() method in ConcreteAcceptor class expects (for a ConcreteAcceptor<Number> ) arguments of type Task<Number> and Number.
- assigning a ConcreteAcceptor<Number> to a ConcreteAcceptor<? super Integer> is syntactically correct
- Now let's take a look at line: ca.accept(at, new Integer(1));
It seems right because: ca is a ConcreteAcceptor<? super Integer> and as such it would expect a Task<? super Integer> as first argument. We are passing a Task<Integer> which can be assigned to a Task<? super Integer> but it fails. Why?
Well, it really looks ugly when you change:
by
because in ca.accept(at, new Integer(1)) we are passing a Task<Integer> where a Task<Number> is expected. And that would be wrong.
Fortunately, the compiler does nto allow to do that from the very beginning.
I cannot give you a real explanation of how this works, but after analyzing the implications in the modified version of the code, it looks good that the compiler is able to reject those kinds of conversions.
[ June 11, 2007: Message edited by: Sergio Tridente ]