Java 使用 PropertyChangeSupport 和 PropertyChangeListener 检测变量更改
当某些第三方代码更改变量时,我试图打印出调试语句。例如,考虑以下内容:
public final class MysteryClass {
private int secretCounter;
public synchronized int getCounter() {
return secretCounter;
}
public synchronized void incrementCounter() {
secretCounter++;
}
}
public class MyClass {
public static void main(String[] args) {
MysteryClass mysteryClass = new MysteryClass();
// add code here to detect calls to incrementCounter and print a debug message
}
我没有能力更改第 3 方 MysteryClass,因此我认为我可以使用 PropertyChangeSupport 和 PropertyChangeListener 来检测对 SecretCounter 的更改:
public class MyClass implements PropertyChangeListener {
private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
public MyClass() {
propertySupport.addPropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("property changing: " + evt.getPropertyName());
}
public static void main(String[] args) {
MysteryClass mysteryClass = new MysteryClass();
// do logic which involves increment and getting the value of MysteryClass
}
}
不幸的是,这不起作用,并且我没有调试消息打印出来。有人看到我的 PropertyChangeSupport 和 Listener 接口的实现有什么问题吗?我想每当调用incrementCounter 或secretCounter 的值发生变化时打印调试语句。
I'm trying to print out debug statements when some third party code changes a variable. For example, consider the following:
public final class MysteryClass {
private int secretCounter;
public synchronized int getCounter() {
return secretCounter;
}
public synchronized void incrementCounter() {
secretCounter++;
}
}
public class MyClass {
public static void main(String[] args) {
MysteryClass mysteryClass = new MysteryClass();
// add code here to detect calls to incrementCounter and print a debug message
}
I don't have the ability to change the 3rd party MysteryClass, so I thought that I could use PropertyChangeSupport and PropertyChangeListener to detect changes to the secretCounter:
public class MyClass implements PropertyChangeListener {
private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
public MyClass() {
propertySupport.addPropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("property changing: " + evt.getPropertyName());
}
public static void main(String[] args) {
MysteryClass mysteryClass = new MysteryClass();
// do logic which involves increment and getting the value of MysteryClass
}
}
Unfortunately, this did not work and I have no debug messages printed out. Does anyone see what is wrong with my implementation of the PropertyChangeSupport and Listener interfaces? I want to print a debug statement whenever incrementCounter is called or the value of secretCounter changes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我很确定
PropertyChangeListener
机制仅在通过PropertyEditor
机制设置属性时才有效,而不是通过 getters 和 setters我可能会尝试使用 AspectJ,但你只能建议方法调用,不能建议执行,因为第三方类是最终的。
I'm pretty sure the
PropertyChangeListener
mechanism only works if you set the properties through thePropertyEditor
mechanis, not through getters and settersI'd probably try it with AspectJ, but you can only advise the method calls, not the execution, as the third party class is final.
我很遗憾地说,但是在 MysteryClass 实现的情况下,如果您无法更改它的实现,那么您就不能更改它,顺便说一句,您的 PropertyChangeListener PropertyChangeSupport 概念全部错误。要使其正常工作,PropertyChangeSupport MysteryClass 请参阅有关绑定属性的 Java Beans 教程
您可以做的就是用您自己的类包装该类,例如 MysteryClassWithPrint 它将实现所有公共方法作为对 MysteryClass 内部实例的委托并打印消息
然后将所有
new MysteryClass();
替换为 newMysteryClassWithPrint();
I am sorry to say this but in case of that MysteryClass implementation and if you are not able to change it's implementation you can not and by the way you got the PropertyChangeListener PropertyChangeSupport concept all wrong. to make it work PropertyChangeSupport MysteryClass see the Java Beans Tutorial on Bound properties
what you can do is to wrap the class with your own class lets say MysteryClassWithPrint that will implement all the public methods as delegation to the internal instance of MysteryClass AND print messages
and then replace all
new MysteryClass();
with newMysteryClassWithPrint();