Java:从bound-method-reference获取对象

时间:2015-12-28 14:15:49

标签: java events observer-pattern method-reference

TL; DR

是否有某种方法可以从使用方法引用调用的函数my_object中获取do_something

other_object.do_something(my_object::some_method);

全文......

背景:我正在建立一个系统,其中模块通过将事件传递给彼此来进行通信。每个模块通过<EventType> void eat_event(EventType ev)形式的一种或多种方法消耗事件。 (可能有不同的方式来吃事件,并且给定的模块可能能够使用不同的方法来吃不同类型的事件)。每个模块都维护一个消费者列表,并向他们发送事件。模块通过add_listener方法连接:

class Module{
    ...
    public <EventType> void add_listener(Consumer<EventType> consumer){
        this.listeners.add(consumer);
    }
}

在初始化代码中,我将模块绑定在一起,如:

module_1.add_listener(module_2::eat_event);

现在,问题: 有没有办法提取方法引用module_2所属的对象(在本例中为module_2::eat_event)?假设,出于某种原因,我希望module_1维护一个包含它发送事件的模块的表。目前,我必须将add_listener定义更改为:

public <EventType> void add_listener(Module dest_module, Consumer<EventType> consumer){...}

并绑定:

module_1.add_listener(module_2, module_2::eat_event);

当您将所有内容绑定在一起时看起来多余,并为编程错误留出空间,因为您可能会意外指定不属于目标模块的方法。

真正的问题:我为了这个问题简化了问题,但真正的问题是我正在构建一个中间“路由器”类,它可能想要缓冲{的输出在将它们送到module_1之前{1}}。问题是,当我通过路由器类指定连接时,我需要知道模块之间的依赖关系结构,当您传入源模块和目标模块的方法引用时,这种结构会丢失。

到目前为止的结论

(2015年12月29日15:30更新) 不,据我所知,没有办法做到这一点。

但是,我发现我不需要为我的程序执行此操作...因此,虽然可能有某些原因要执行此操作,但我的不是其中之一。

1 个答案:

答案 0 :(得分:1)

当你定义一个类型为Consumer<EventType>的参数的方法时,没有保证Consumer的实现是一个方法引用,如果它是通过方法引用实现的,那么捕获了特定类型的对象。如果你想在两个参数之间声明一个特定的依赖关系,你可以反过来这样做:

public <M extends Module, E> void add_listener(M dest_module, BiConsumer<M,E> listener){
    ...
}

由于该方法需要记住dest_modulelistener之间的关联,因此将dest_module作为accept方法的第一个参数提供应该没有问题listener

在这个星座中,监听器根本不需要捕获模块实例。从您的示例派生的典型用例如下:

module_1.add_listener(module_2, TypeOfModule2::eat_event);

此处,方法引用不捕获模块实例,并且侦听器通知实现最终将在注册时提供的实例上调用eat_event方法。所以你在这里没有冗余,也没有混合模块实例的机会。

然而,如上所述,没有关于add_listener的调用者如何实现侦听器接口的保证。你无法阻止抵消实施的所有可能性。你只能尝试使有意的实现变得容易,并且难以实现更难实现的东西。