我想知道是否有任何方法可以在程序运行时观察变量值的变化。当然不使用调试器我想以编程方式进行。例如:
class A
{
public static int valueToBeWatched;
}
所以在运行时,如果在我的项目中任何类的任何方法中修改了这个值MyValueChangeListner
事件应该被调用。
我想知道是否有任何方法可以在程序运行时观察变量值的变化。当然不使用调试器我想以编程方式进行。例如:
class A
{
public static int valueToBeWatched;
}
所以在运行时,如果在我的项目中任何类的任何方法中修改了这个值MyValueChangeListner
事件应该被调用。
你不能。Java 本身没有内置监视修改钩子。显然,您可以进行轮询。但那样它就不会是“活的”。
AspectJ可能允许这样的想法,但我不确定它是否适用于原始变量,或者仅当您使用 getter 和 setter 时。
干净的Java方式是制作变量private
并使用getter和setter。
private valueToBeWatched;
public void setValue(int newval) {
valueToBeWatched = newval;
notifyWatchers();
}
public int getValue() {
return valueToBeWatched;
}
static
附带说明一下,尽可能避免。特别是public
但不是final
。
您需要将类型替换为int
一个类,该类将在值更改时调用您的侦听器。您可能希望在实际未更改时忽略设置该值。
例如
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;
}
您可以使用字节码注入来执行此替换,但更改原始代码要简单得多。
另一种方法是监视值以定期查找更改。除非值变化非常缓慢,否则您可能看不到所有变化。您可以使用 Debugger API 来执行此操作,但它并不简单,除非您已经熟悉该 API,否则我不建议您使用它。
Java 调试器 API 链接
http://java.sun.com/javase/technologies/core/toolsapis/jpda/
如果您可以使用 Oracle 的最新 Java SE JDK,那么我建议使用javafx.beans.property和javafx.beans.value API。
这是一些基本代码:
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);
}
}
}
这是输出:
该值已从 9.0 更改为 3.0
该值已从 3.0 更改为 6.0
如前所述,这个问题可以通过编写一个代理来解决所提供的字段的变化(参见fieldWatch)。代理必须使用与 C 调用兼容的语言进行编译,并在 VM 启动时通过-agentpath:<path-to-agent>=<options>
开关调用。
更高级别的选项是使用JPDA /JDI附加到正在运行的进程,它将上述调用包装在 (Java) ModificationWatchpointEvent中。