我读了 600 页的 Java 文本,却遇到了一些令人困惑的问题。
在 Swing 编程部分中,它展示了创建“EventListener”来处理按钮单击的三种不同方法。首先,它展示了如何在实现 ActionListener
的类中使用函数,然后如何使用实现 ActionListener
的嵌套类,最后展示如何使用 Lambda 表达式。
前两种方法使用本质上相同的函数(评论是我的):
…
button1=new JButton("foobar"); //create a button object
button1.addActionListener(this); //add an event handler to it
…
public void actionPerformed(ActionEvent e) { //event handler (standalone or in a class)
if (e.getSource() == button1) { //check if event source is the button
//do something
}
}
这非常简单;创建一个按钮,并将按钮对象本身或包含函数的单独类传递给 addActionListener
以向按钮添加事件处理程序。
Lambda 表达式使用了一个稍微精简的函数,看起来非常相似:
…
button1 = new JButton("foobar"); //create a button
button1.addActionListener(e -> button1Click()); //set button1Click as event handler
…
public void button1Click() { //event handler
//do something
}
令我困惑的是缺少 Activity 信息。在前两种方法中,函数必须检查事件源以查看它是否是按钮,但 Lambda 表达式只是假设/知道事件源是按钮。怎么办?
从哪里得到的?对 addActionListener
的调用以 button1
开头,但 Lambda 表达式中未提及任何地方。另外,这是否意味着使用 Lambda 表达式会限制可用信息?函数中没有对 e
的引用,因此无法访问函数来查找键、时间戳等信息。
(哦,为什么 Java 将其称为事件监听器,而不是像几乎所有其他语言一样的处理程序,这超出了我的理解。他们说 Java 和 JavaScript 很相似只是名义上的……)
最佳答案
请注意,在非 lambda 情况下传递的监听器是 this
,即设置按钮的对象。据推测,该对象(某些 Controller 或容器)可能充当多个按钮的事件监听器,因此必须区分哪个按钮发送了事件。另一方面,lambda 正在创建一个仅附加到该单个按钮的一次性处理程序实例,因此不存在歧义。
关于Java Lambda 表达式和事件信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37095701/