java - 使用 this::some_method_reference 作为监听器创建一个新的 lambda 引用。为什么?

标签 java

我试图理解为什么在注册为监听器时使用 this::someMethod 会在我每次注册时创建多个 lambda 实例。

例如。以下代码已损坏,我试图了解 Java 设计者为何以这种方式实现它的基本原理。

class A {
  private JMenuItem menuItem = new JMenuItem();

  public void addListener() {
    menuItem.addActionListener(this::clickHandler);
    menuItem.removeActionListener(this::clickHandler);
  }

  private void clickHandler(final ActionEvent e) {
     /** do stuff here **/
  }
}

如果执行上述操作,则永远不会从 JMenuItem 中删除监听器。我本以为第二个 lambda 会与第一个相同?

渴望理解为什么这样做。

最佳答案

在运行时,Lambda 是对象,如 JLS 中所述:

At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a lambda expression is distinct from execution of the lambda body.

Either a new instance of a class (...) is allocated and initialized, or an existing instance of a class (...) is referenced.

所以,这解释了:

menuItem.addActionListener(this::clickHandler);
menuItem.removeActionListener(this::clickHandler);

与此类似(但不完全相同):

menuItem.addActionsListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        this.clickHandler(e);
    }
});
menuItem.removeActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        this.clickHandler(e);
    }
});

这可以解释为什么您的代码没有按预期运行。

请注意,将 lambda 作为对象重用取决于 JVM 实现。

关于java - 使用 this::some_method_reference 作为监听器创建一个新的 lambda 引用。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57328438/

相关文章:

java - 在运行时加载驱动程序 jar 文件导致 Perm Gen Space Error

java - 如何生成特定的 JNI header

java - 我可以创建集合数组吗?

java - Android 中使用蓝牙进行数据传输

java - 字符串(2019 年 8 月 19 日 11 :05) to date format

java - 在Java中读取CSV文件不起作用?

java - 将日期从 DD-MMM-YYYY 重新格式化为 YYYYDDMM 或 YYYYMMDD

java - 设置对象的颜色

java - 使用 Java 和 RSA 加密网络流量

java - 在适配器中打开对话框