我想知道是否有任何方法可以让我在程序运行时观察变量值的变化。当然不使用调试器我想这样做以编程方式。例如:
class A
{
public static int valueToBeWatched;
}
因此,在运行时,如果在我的项目中的任何类的任何方法中修改此值MyValueChangeListner
,则应调用该事件。
答案 0 :(得分:11)
你做不到。 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
。
答案 1 :(得分:6)
您需要将类型int
替换为一个类,只要值发生变化,它就会调用您的侦听器。您可能希望在实际没有更改时忽略设置值。
e.g。
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/
答案 2 :(得分:4)
如果您可以使用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
答案 3 :(得分:1)
如上所述,问题可以通过编写代理来收听所提供字段的更改来解决(请参阅fieldWatch)。代理必须使用C调用兼容语言进行编译,并在VM启动时使用-agentpath:<path-to-agent>=<options>
开关调用。
更高级别的选项是使用JPDA / JDI附加到正在运行的进程,该进程将上述调用包装在(Java)ModificationWatchpointEvent中。