简体   繁体   中英

Calling non-static method reference on an object with an argument

I'm creating an event handling framework and would like to do the following:

// E: event listener interface, T: event class
class EventManager<E, T> {

    ArrayList<E> listeners = new ArrayList<E>();

    // `method` is some sort of reference to the method to call on each listener. There is no `MethodReference` type, I just put it there as I'm not sure what type should be in its place
    protected void notifyListeners(MethodReference method, T eventObj) {
        for (E listener : listeners) // call `method` from `listener` with `eventObj` as an argument
   }
}

class SpecialisedEventManager extends EventManager<SomeListener, SomeEvent> {

    // Some method that would want to notify the listeners
    public void foo() {
        ...
        // I would like onEvent() to be called from each listener with new SomeEvent() as the argument
        notifyListeners(SomeListener::onEvent, new SomeEvent());
        ...
    }

    // Some other method that would want to notify the listeners
    public void bar() {
        ...
        notifyListeners(SomeListener::onOtherEvent, new SomeEvent());
        ...
    }

}

interface SomeListener {
    public void onEvent(SomeEvent event);
    public void onOtherEvent(SomeEvent event);
}

But I'm not sure how to reference the onEvent() and onOtherEvent() methods so that they are called from each listener object with the proper argument. Any ideas?

A method reference is just a way to implement a functional interface, so you have to either, define yourself an appropriate interface or search the predefined types for a match.

Since your listener method consumes a target listener instance and an event object and doesn't return a value, BiConsumer is an appropriate type:

protected void notifyListeners(BiConsumer<E,T> method, T eventObj) {
    for(E listener: listeners)
        method.accept(listener, eventObj);
}

The method references SomeListener::onEvent and SomeListener::onOtherEvent have the form “Reference to an instance method of an arbitrary object” where the caller provides the target instance to invoke the method on, similar to the lambda expressions (l,e) -> l.onEvent(e) and (l,e) -> l.onOtherEvent(e) , which is why the target instance becomes the first functional parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM