Java:从绑定(bind)方法引用获取对象

标签 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);
    }
}

在初始化代码中,我将模块绑定(bind)在一起,如下所示:

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){...}

并绑定(bind):

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

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

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

到目前为止的结论

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

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

最佳答案

当您定义具有 Consumer<EventType> 类型参数的方法时,不保证 Consumer 的实现是方法引用,也不是说,如果它是通过方法引用实现的,则它捕获了特定类型的对象。如果你想声明两个参数之间的特定依赖关系,你可以反过来做:

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

因为该方法应该记住 dest_module 之间的关联和 listener ,提供 dest_module 应该没有问题作为 accept 的第一个参数listener的方法.

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

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

这里,方法引用不会捕获模块实例,监听器通知实现最终将调用 eat_event注册时提供的实例上的方法。因此,这里没有冗余,也没有机会混淆模块实例。

但是,如前所述,无法保证 add_listener 的调用者如何调用实现监听器接口(interface)。您无法阻止所有抵消实现的可能性。您只能尝试让有意的实现变得容易,而抵消的东西则更难实现。

关于Java:从绑定(bind)方法引用获取对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34495181/

相关文章:

windows - 如何使用 Write-EventLog 在事件日志中显示任务类别的字符串名称?

php - symfony/事件调度程序未收到第一次调度

java - SWT:Composite 上的 addFilter 或 addKeyListener

javascript - prototypejs观察IE7

java - Tomcat 上具有不同 Grails 版本的多个应用程序

java - 在快速排序中使用最后一个元素作为枢轴时无法解决错误

java - 如何使用eclipse在后台运行倒计时

java - 使用 jclouds API 创建 aws-ec2 实例

java - 如何在java中实现相反的观察者模式?

java - 连接 GUI (Swing) 和业务逻辑