Invalid method reference with generics

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 27 00:35:45 PDT 2013


On 26/06/13 18:43, Nick Williams wrote:
> However, I CAN do this (it compiles and runs just fine):
>
> register(new ApplicationListener<Event1>() {
>      public void onApplicationEvent(Event1 event) { }
> });
>
> So, by extension, I SHOULD be able to do this, but can't:
>
> void onApplicationEvent(Event1 event) { }
> register(this::onApplicationEvent);
>
> We have inconsistent behavior here. In your example, both the method reference and the anonymous inner class are illegal. In my use case, the compiler allows the anonymous inner class but prohibits the method reference. That inconsistency is a real problem. There is_no_  semantic difference between what I'm doing with the anonymous inner class and what I'm doing with the method reference. Zero. The method signatures are identical (I event named them the same here to drive home the point), but one works and the other doesn't.
>
> Nick
>
Yes and no - the inner class you are creating is a subtype of:

ApplicationListener<Event1>

while the type inferred by the compler as a target is:

ApplicationListener<ApplicationEvent> (wildcard removed as per spec)

This is why you get the 'weird' behavior. To express what you mean, you 
need to do the following:

    public static <Z extends ApplicationEvent> void 
register(ApplicationListener<Z> listener) { }

The compiler will infer Z == Event1 and all will be fine. Well, it will 
fail with an inference error for now, but we have plans to fix that in 
the future.

Maurizio


More information about the lambda-dev mailing list