2013-07-11 60 views
0

我試圖開發一個模擬應用程序。我需要監視模擬環境中的所有Java對象。在執行模擬期間,用戶定義的對象方法會在每個記號中週期性地調用。我想跟蹤所有對象的所有字段值和方法返回值。例如,動態監控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這樣的監視機制。我在模擬執行過程中如何做到這一點。我需要觀察所有字段和方法返回值,例如執行中的調試代碼。

任何想法。

感謝想法

回答

0

如果我知道你要問什麼正確的,你想一個方法調用你的註釋之後捕捉到原始字段的值的變化。

對此有很多可能的解決方案,具體取決於客戶端代碼的簡單程度,您要編寫的框架的複雜程度以及實際需要執行的操作。這裏有一些想法:

  • 有模擬對象的公共基類,並給子類的方式存儲在Map<String,Object>你給他們的價值觀,而不是原始現場;他們提供Map的子類,它記錄了更改,並且您的代碼可以簡單地向對象詢問自上次調用後發生了什麼變化
  • 當您加載它時使用類似BCEL的東西來替代動態字節碼,並替換當地現場與調用動態生成getter和setter訪問,做上述簿記有
  • 做好以上,但在編譯時通過包含記賬代碼中動態生成的子類

最後兩個選項是不平凡實施,所以我強烈建議先考慮第一個選項。

+0

感謝您的回答蒂姆。第一個選項也是我的解決方案。但是我想要改變開發者觀看Java調試器等所有表達式。我們希望在執行過程中觀察監視表達式,而不會影響代碼的執行行爲。調試器儀器在運行時是字節碼嗎? – icakirlar

+0

爲您的Map添加一些監聽器支持 - 重寫put()來通知監聽器發生了什麼變化。然後,將任何類型的用戶界面粘貼在上面。 –