如何删除用作侦听器的lambda表达式/方法句柄?

Java 8引入了lambda表达式 ,这是一件好事。 但现在考虑重写这段代码:

class B implements PropertyChangeListener { void listenToA(A a) { a.addPropertyChangeListener(this); } void propertyChange(PropertyChangeEvent evt) { switch(evt.getPropertyName()) { case "Property1": doSomething(); break; case "Property2": doSomethingElse(); case "Property1": doSomething; break; break; } void doSomething() { } void doSomethingElse() { } } class A { final PropertyChangeSupport pcs = new PropertyChangeSupport(this); void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } void removePropertyChangeListener(PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } } 

使用lambda表达式和方法引用,不再需要B实现PropertyChangeListner因为我们可以编写

 class B { void listenToA(A a) { // using method reference a.addPropertyChangeListener("Property1", this::doSomething); // using lambda expression a.addPropertyChangeListener("Property2", e -> doSomethingElse()); } void doSomething(PropertyChangeEvent evt) { } void doSomethingElse() { } } class A { final PropertyChangeSupport pcs = new PropertyChangeSupport(this); void addPropertyChangeListener(String name, PropertyChangeListener listener) { pcs.addPropertyChangeListener(name, listener); } void removePropertyChangeListener(String name, PropertyChangeListener listener) { pcs.removePropertyChangeListener(name, listener); } } 

我认为新代码不仅更短,而且更简洁,更易于理解。 但是在阅读了这里给出的答案后( 这个问题的副本,但我认为问题和答案更加清晰),我看不到实现一个名为stopListening()的方法,它会再次删除监听器。

我相信我不是第一个偶然发现这一点的人。 那么有没有人找到一个很好的解决方案,如何使用方法句柄,如本例所示,仍然能够在以后再次删除侦听器?

UPDATE

那很快。 在Mike Naklis和Hovercraft Full Of Eels的答案的基础上,我最终得到了这个:

 class B { void listenToA(A a) { a.addPropertyChangeListener("Property1", doSomething); a.addPropertyChangeListener("Property2", doSomethingElse); } final PropertyChangeListener doSomething = evt -> {}; final PropertyChangeListener doSomethingElse = evt -> {}; } 

您可以按如下方式声明侦听器:

 private final PropertyChangeListener myProperty1Listener = this::doSomething; private final PropertyChangeListener myProperty2Listener = e -> doSomethingElse()); 

然后,您可以添加您的侦听器:

 // using method reference a.addPropertyChangeListener( "Property1", myProperty1Listener ); // using lambda expression a.addPropertyChangeListener( "Property2", myProperty2Listener ); 

你可以删除它们:

 a.removePropertyChangeListener( "Property1", myProperty1Listener ); a.removePropertyChangeListener( "Property2", myProperty2Listener ); 

您可以使用lambdas并仍然使用变量。 例如,如果你有:

 class B { private PropertyChangeListener listener1 = this::doSomething; private PropertyChangeListener listener2 = e -> doSomethingElse(); void listenToA(A a) { // using method reference a.addPropertyChangeListener("Property1", listener1); // using lambda expression a.addPropertyChangeListener("Property2", listener2); } 

然后,在需要的时间和地点移除listener1或listener2会很容易。

还有其他方法,因为PropertyChangeSupport对象有一个getPropertyChangeListeners() ,如果需要,它将允许删除for循环中的所有侦听器。

 class A { final PropertyChangeSupport pcs = new PropertyChangeSupport(this); void addPropertyChangeListener(String name, PropertyChangeListener listener) { pcs.addPropertyChangeListener(name, listener); } void removePropertyChangeListener(String name, PropertyChangeListener listener) { pcs.removePropertyChangeListener(name, listener); } public void removeAllListeners() { for (PropertyChangeListener l : pcs.getPropertyChangeListeners()) { pcs.removePropertyChangeListener(l); } } }