Java 使用this::some_method_reference作为侦听器将创建一个新的lambda引用。为什么?

Java 使用this::some_method_reference作为侦听器将创建一个新的lambda引用。为什么?,java,Java,我试图理解为什么在注册为侦听器时使用此::someMethod会在每次注册时创建多个lambda实例 比如说。下面的代码被破坏了,我试图理解为什么java设计人员以这种方式实现它 class A { private JMenuItem menuItem = new JMenuItem(); public void addListener() { menuItem.addActionListener(this::clickHandler); menuItem.remove

我试图理解为什么在注册为侦听器时使用此::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是对象,如中所述:

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 **/
  }
}
在运行时,lambda表达式的求值与类实例创建表达式的求值类似,只要正常完成生成对对象的引用。lambda表达式的计算不同于lambda体的执行

要么分配并初始化类(…)的新实例,要么引用类(…)的现有实例

因此,这说明:

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的实现