需求:Java在一个A类中监听另一个B类里面一个整形变量N的变化,B类中N值一变化,A就得到这个变化的值
实现:上一篇博客是自己用观察者模式手写监听器来实现,后来无意中发现Java有内置的属性监听器,在java.beans包下的
PropertyChangeListener类和PropertyChangeSupport类。话不多说,直接上代码。
1.被监听的B类,在被监听的属性n的set方法中通知更新。当n发生变化时,使用PropertyChangeSupport对象的firePropertyChange方法,它会将一个事件发送给所有已经注册的监听器。该方法有三个参数:属性名字、属性旧值以及属性新值。注意:如果旧值和新值相同,不会触发事件。
public class B {
private int n = 0;
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
public int getN() {
return n;
}
public void setN(int n) {
int oldN = this.n;
this.n = n;
changes.firePropertyChange("n", oldN, n);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
changes.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
changes.removePropertyChangeListener(listener);
}
}
2.在主类A中使用匿名内部类来实现监听器,propertyChange方法会在firePropertyChange触发了事件之后捕获该事件然后执行。也可以通过implements PropertyChangeListener接口实现。
public class A {
public static void main(String[] args) {
B b = new B();
b.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("属性名称:" + evt.getPropertyName());
System.out.println("属性旧值:" + evt.getOldValue());
System.out.println("属性新值:" + evt.getNewValue());
}
});
b.setN(1);
}
}
这样就实现了我们文章开头的需求啦,是不是so easy!其实这种方式跟上一篇博客中的观察者模式原理是一样的。唯一的区别就是PropertyChangeSupport类内部用的数据结构是Map,我用的是Vector,实现效果是一样的。如果是简单的属性监听需求的话,不妨使用这种方式,可以减少代码量哦。