【问题标题】:How does passing a lambda expression (or anonymous class) work in "addActionListener" and similar behaving methods?传递 lambda 表达式(或匿名类)如何在“addActionListener”和类似的行为方法中工作?
【发布时间】:2021-07-08 22:25:48
【问题描述】:

我一直在尝试学习如何使用 lambda 函数,这似乎很有意义,但后来我看到它作为函数参数传入,特别是在 addActionListener() 方法中,首先他们使用了一个匿名类并显示如何用 lambda 表达式替换它。我尝试查看 Java Docs 中函数的定义以更好地理解它,但我没有任何运气理解代码是如何工作的,因为它看起来不像任何东西直接与对象的方法或 lambda 表达式交互(代码来自教程):

...
myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("You pressed a button");
    }
});
...
myButton.addActionListener(
    (e) -> System.out.println("You pressed a button");
);

当按钮被按下时,addActionListener 方法中的方法(更具体地说是EventListenerList 类中的add 方法)如何被调用?它是如何工作的?它是否发生在 Java 本身的某个地方,但表面上没有显示出来?

第 1124 行:https://developer.classpath.org/doc/javax/swing/AbstractButton-source.html
第 142 行:https://developer.classpath.org/doc/javax/swing/event/EventListenerList-source.html

感谢您提供的任何帮助。

【问题讨论】:

  • 当 Java 应用程序收到事件通知时,它会通过将事件分派到适当的 UI 组件来处理该事件。该过程的一部分是调用任何适当的已注册侦听器的适当方法。其中很多可能是内部代码,至少在 JavaFX 中(我不太熟悉 AWT/Swing 内部的工作方式)。
  • lambda 版本与第一个代码相同,但 Java 正在从上下文中进行大量推断(所需的类、参数类​​型)。 lambda 版本只是非 lambda 版本的简写(即“语法糖”)。
  • @JimGarrison 这部分我理解,但我要问的是,如果在 add 类的 add 方法中没有明确调用它,它是如何由 Java 本身执行的(因为那是在addActionListener 中使用的方法。沿着这些思路。
  • 如果您想查看实现,您可以随时使用调试器来单步调试代码。处理事件时查看执行流程的一种快速方法是在动作侦听器中调用Thread.dumpStack();然后你可以使用堆栈跟踪来跟踪代码。
  • 举个例子,对于一个按钮,动作监听器似乎被调用的地方是在javax.swing.AbstractButton#fireActionPerformed(java.awt.event.ActionEvent)方法中。

标签: java function lambda event-handling


【解决方案1】:

在这两种情况下,ActionListener 的新匿名子类被临时“创建”(它是短暂的),并且该匿名类的单个实例对象被创建。匿名类实例有一个方法,actionPerformed()

因此,在对addActionListener() 的调用中,您传递的是对新创建的匿名类instance 的引用。 addActionListener() 将该引用添加到其事件处理程序列表并返回。

稍后,当事件发生时,框架向myButton 对象发送一个事件,该对象查看其事件处理程序列表并依次调用每个处理程序上的actionPerformed()。您的匿名实例是被调用的处理程序之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    相关资源
    最近更新 更多