如何观察变量的变量

我想知道是否有任何方法可以在程序运行时观察变量值的变化。 当然不使用调试器我想以编程方式进行 。 例如:

class A { public static int valueToBeWatched; } 

因此,在运行时,如果在我的项目中的任何类的任何方法中修改此值,则应调用此值MyValueChangeListner事件。

您需要将类型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; } 

您可以使用字节代码注入执行此替换,但更改原始代码非常简单。

另一种方法是监视值以定期查找更改。 除非值变化非常缓慢,否则您可能看不到每一个变化。 您可以使用调试器API执行此操作,但这并不简单,除非您已熟悉API,否则我建议您不要使用它。

Java调试器API链接

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/

你不能。 Java本身没有内置的watch-on-modification钩子。 显然,你可以做民意调查。 但那时它不会“活着”。

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

如果您可以使用Oracle提供的最新Java SE JDK,那么我建议使用javafx.beans.propertyjavafx.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 { @Override public void changed(ObservableValue 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:=开关调用。

更高级别的选项是使用JPDA / JDI附加到正在运行的进程, JPDA / JDI将上述调用包装在(Java) ModificationWatchpointEvent中 。