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 t开发者_StackOverflowhe 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.
I'm pretty sure the PropertyChangeListener
mechanism only works if you set the properties through the PropertyEditor
mechanis, not through getters and setters
I'd probably try it with AspectJ, but you can only advise the method calls, not the execution, as the third party class is final.
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 new MysteryClassWithPrint();
精彩评论