Invalid method reference with generics
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jun 26 10:27:18 PDT 2013
On 26/06/13 18:13, Nick Williams wrote:
> That compiles and runs (I just tested it), but the two uses of register are completely opposite. Register with the anonymous inner class works as I expect: I can pass in an ApplicationListener whose type_extends_ ApplicationEvent. Register with the method reference is opposite: I can pass in an ApplicationListener whose type_is extended by_ ApplicationEvent. I am very convinced that that's wrong. In fact, my IDE highlights the anonymous inner class as a warning that says "Anonymous ApplicationListener<Event1>" can be replaced with lambda," but when I let it replace it I get incompatible parameter types upon compilation.
I think the fact that the IDE suggests that a lambda might be use is a
bug in the lambda detector; a lambda cannot be used as, a lambda
parameter type must be identical to that of the descriptor itr will be
passed to. Subtyping is only allowed for method references, but the
other way around, not the one you are asking for.
Example:
interface I {
void m(Number n)
}
void g1(Object o)
void g2(Number n)
void g3(Integer i)
void m(I i);
m(this::g1); //ok, Number subtype of Object
m(this::g2); //ok, Number subtype of Number
m(this::g3); //error, Number not a subtype of Integer
Note that this semantics is quite standard, as parameter types in
function types are treated in a contravariant fashion (i.e. the function
type accepting a more constrained domain is more general - this comes
from Liskov - a subtype of a function type cannot start arbitrarily
rejecting input values that were accepted by a super type).
Maurizio
More information about the lambda-dev
mailing list