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