Java 没有方法作为一等函数,也就是说,该语言不提供对您可以像在其他语言中一样传递的方法的引用。对于问题中概述的结构,您最好的选择是使用反射。
import java.lang.NoSuchMethodException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
public class MyButton {
private Object onClickObject;
private Method onClickMethod;
public void OnClick(Object object, String methodName) throws NoSuchMethodException {
OnClick(object, object.getClass().getMethod(methodName));
}
public void OnClick(Object object, Method method) {
this.onClickObject = object;
this.onClickMethod = method;
}
// MyButton calls this method every time the button is clicked, in
// order to inform the external event handler about it
protected void onClick() throws IllegalAccessException, InvocationTargetException {
onClickMethod.invoke(onClickObject);
}
}
但也要注意,因为方法不是一等公民,所以上述方法并不是在 Java 中实现事件监听器的规范方法。相反,Java 方式是定义一个带有回调方法的接口,可能是这样的:
public interface ButtonListener {
public void OnClick();
}
(这是假设您不必将任何参数传递给事件处理程序。通常,这是不能假设的,因此除了 a 之外ButtonListener
,您还有一个ButtonEvent
封装参数并传递给方法(s ) 在接口中定义。)
然后,如果您编写一个有兴趣在单击某个按钮时接收事件的类,则该类必须实现ButtonListener
. 反过来,MyButton
该类必须提供一种方法来注册侦听器:
public MyButton {
protected List<ButtonListener> buttonListeners;
public void addButtonListener(ButtonListener listener) {
...
}
public void removeButtonListener(ButtonListener listener) {
...
}
protected void fireButtonEvent() {
...
}
}
我相信您已经在 Java 标准类库中看到过很多这种模式,尤其是在java.awt
和javax.swing
-- 例如java.awt.event.ActionListener
,参见 AWT 用于按钮事件的模式。