我试图理解为什么在注册为监听器时使用 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/