我正在尝试开发一个模拟应用程序。我需要监视模拟环境中的所有java对象。在模拟的执行过程中,用户定义的对象方法会在每个刻度中周期性地调用。我想跟踪所有对象的所有字段值和方法返回值。例如,
public class Person{
int energy,x,y;
public Person(){
this.energy = new Random().nextInt(0,10);
}
@ScheduledMethod(start=1, interval=1)
void step(){
energy--;
// move random x,y
move();
}
void move(){
this.x= new Random().nextInt(1,50);
this.y = new Random().nexInt(1,50);
} }
在我的模拟器中,每个人在每个勾选中的能量值都会被追踪并保存,直到人死。模拟开发人员通常使用随机化函数,因此两次调用一个方法可能不会返回与Person的x,y值相同的值。
通过使用反射API,我可以动态访问字段值(可以访问人员的能量值。)但我需要访问方法返回值(人员的x,y值在每次移动调用中都会发生变化)。当我使用反射调用方法时,该方法的执行被扭曲。因此,我需要以不同的方式处理方法调用。
我提到我需要一个像JAVA调试API这样的监控机制。我是如何在模拟执行过程中做到这一点的。我需要观察所有字段和方法的返回值,比如执行中的调试代码。
任何想法。
感谢您的想法
如果我正确理解您的要求,那么您希望在使用注释调用方法后捕获原始字段值的更改。
有很多可能的解决方案,这取决于客户端代码需要有多简单,你想写的框架有多复杂,以及你实际需要它做什么
- 为模拟对象提供一个通用基类,并为子类提供一种将值存储在您给它们的
Map<String,Object>
中的方法,而不是存储在原始字段中;它们提供了Map
的一个子类,用于记录更改,并且您的代码可以简单地询问对象自上次调用以来发生了什么更改 - 当您加载字节码时,使用BCEL之类的东西动态地检测字节码,并用对动态生成的getter和setter的调用替换本地字段访问,并在那里进行上述记账
- 执行上述操作,但在编译时通过动态生成包含记账代码的子类
最后两个选项的实现非常简单,所以我强烈建议先考虑第一个选项。