这与 Guava 的EventBus
类可以克服的方法重载和接口的限制有关。
对于接口,请考虑以下场景:
我有为多种形式的输入调用的相同代码。例如,一个监听器监听鼠标事件、按键事件和焦点事件,但所有方法都做同样的事情:重绘源。这意味着我的代码将如下所示:
public class BunchOfListeners implements MouseListener, KeyListener, FocusListener {
@Override
public void focusGained(FocusEvent e) {
doSomething(e);
}
@Override
public void focusLost(FocusEvent e) {
doSomething(e);
}
@Override
public void keyTyped(KeyEvent e) {
doSomething(e);
}
@Override
public void keyPressed(KeyEvent e) {
doSomething(e);
}
@Override
public void keyReleased(KeyEvent e) {
doSomething(e);
}
@Override
public void mouseClicked(MouseEvent e) {
doSomething(e);
}
@Override
public void mousePressed(MouseEvent e) {
doSomething(e);
}
@Override
public void mouseReleased(MouseEvent e) {
doSomething(e);
}
@Override
public void mouseEntered(MouseEvent e) {
doSomething(e);
}
@Override
public void mouseExited(MouseEvent e) {
doSomething(e);
}
public void doSomething(EventObject e) {
((Component) e.getSource()).repaint();
}
}
注意到这有多丑吗?为此有 10 种不同的方法,最终我们唯一关心的是从事件中获取源(由 指定EventObject
,顺便说一句,这就是他们在示例中使用它的原因)并调用repaint
它。
使用 Guava's EventBus
,这变得超级、超级简单。我在课堂上只需要一种方法:GuavaIsAwesome
ComponentRepainter
public class ComponentRepainter {
@Subscribe
public void doSomething(EventObject e) {
((Component) e.getSource()).repaint();
}
}
当你用一个EventBus
和后来的火灾注册这个时,比如说,一个MouseEvent
它:
EventBus eventBus = ... ;
eventBus.register(new ComponentRepainter());
然后:
MouseEvent e = ... ;
eventBus.post(e);
这将调用该doSomething
方法,ComponentRepainter
因为它不仅会将事件触发到@Subscribe
具有MouseEvent
参数的方法,而且还会触发具有可从分配MouseEvent
的参数的任何方法。换句话说,因为MouseEvent
extends EventObject
,番石榴EventBus
会将它传递给任何接受的东西EventObject
。如果我们doSomething
接受了Object
,那么我们可以获取发布到的每个EventBus
事件,使其成为一种全局侦听器(因为Java 中的所有内容都Object
扩展了)。
同样的事情也适用于接口。如果您将具体实现传递给EventBus
某个接口,则将@Subscribe
调用使用该接口(与具体类型相反)的方法。它更加灵活,并且克服了“10 无用方法”的方法。