How to view a variable for changes

I want to know if there is a way so that I can watch the variable change when the program starts. Of course, without using a debugger, I want to do this Programmatically . For instance:

class A { public static int valueToBeWatched; } 

Thus, at run time, if this value of MyValueChangeListner changes in any method of any class in my project, the event should be MyValueChangeListner .

+6
source share
4 answers

You need to replace the int type with the class that your listener will call when the values ​​change. You can ignore setting the value if it has not actually changed.

eg.

  private int value; private final MyValueChangeListener listener; public void setValue(int value) { if(this.value == value) return; listener.changed(this, this.value, value); this.value = value; } 

You can perform this replacement using the byte-code insertion, but changing the source code is very simple.

An alternative is monitoring the value for periodically searching for changes. If the value does not change very slowly, you may not see all the changes. You can use the Debugger API for this, but it's not easy, and I would not suggest you use it if you are not already familiar with the API.

Debug API API Links

http://java.sun.com/javase/technologies/core/toolsapis/jpda/

http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/

http://docs.oracle.com/javase/6/docs/jdk/api/jpda/jdi/

+5
source

You can not. There is no clock mechanism in Java that is built into Java. Obviously, you could do a survey. But then it will not "live."

AspectJ may allow such a reflection, but I'm not sure if it is done for primitive variables, or only when you use getters and setters.

The pure Java way is to make the variable private and use getters and setters.

 private valueToBeWatched; public void setValue(int newval) { valueToBeWatched = newval; notifyWatchers(); } public int getValue() { return valueToBeWatched; } 

In a side note, avoid static whenever possible. In particular, public , but not final .

+10
source

If you can use the latest Java SE JDK from Oracle, I suggest using the javafx.beans.property and javafx.beans.value APIs .

Here is the basic code:

 import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; public class ObservableValues { public static void main(String[] args) { DoubleProperty dp = new SimpleDoubleProperty(9); dp.addListener( new DoubleChangeListener() ); dp.setValue(3); dp.setValue(6); } static class DoubleChangeListener implements ChangeListener<Number> { @Override public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) { System.out.println("the value has changed from " + oldValue + " to " + newValue); } } } 

Here is the result:

value changed from 9.0 to 3.0

value changed from 3.0 to 6.0

+4
source

The issue, as indicated, can be resolved by writing an Agent to listen for changes in the provided field (see fieldWatch ). The agent must be compiled using a C-compatible language and invoked in the virtual machine using the -agentpath:<path-to-agent>=<options> switch.

A higher level parameter must be attached to the running process using JPDA / JDI, which transfers the above call to (Java) ModificationWatchpointEvent .

+1
source

Source: https://habr.com/ru/post/925211/


All Articles