Invalid method reference with generics

Nick Williams nicholas+openjdk at nicholaswilliams.net
Sun Jun 23 10:59:31 PDT 2013


Given this interface:

public interface ApplicationListener<E extends ApplicationEvent>  extends EventListener {
   void onApplicationEvent(E e);
}

And these two events:

public class Event2 extends ApplicationEvent {
   public Event1(Object source) {
       super(source);
   }
}

public class Event2 extends ApplicationEvent {
   public Event2(Object source) {
       super(source);
   }
}

And this class:

public class MyBean {
   public void onEvent1(Event1 event1) { }

   public void onEvent2(Event2 event2) { }

   public void initialize() {
       register(this::onEvent2);
   }

   public static void register(ApplicationListener<? extends ApplicationEvent> listener) { }
   // I've also tried public static void register(ApplicationListener<ApplicationEvent> listener) { }
   // I've also tried public static void register(ApplicationListener<?> listener) { }
   // I've also tried public static void register(ApplicationListener listener) { }
}

Can someone tell my why this fails to compile with the following error?

Error: java: incompatible types: invalid method reference
   incompatible types: x.x.x.ApplicationEvent cannot be converted to x.x.x.Event2

This seems like quite the limitation. Why can't the compiler match onEvent2 to the method in ApplicationEvent?

If I change onEvent2's signature to take an ApplicationEvent instead of an Event2, it compiles fine. If I change register's signature to take an ApplicationListener<Event2> instead of an ApplicationListener<? extends ApplicationEvent>, it also compiles fine. Is there some other way to do what I want to do here?

Note: I also tried public static <E extends ApplicationEvent> void register(ApplicationListener<E> listener) { }, but that resulted in a different error, "Error: java: incompatible types: Cannot instantiate inference variables E because of an inference loop."

Nick


More information about the lambda-dev mailing list