![](/img/trans.png)
[英]Java - library to generate source code changed e.g. by JavaScript from normal source code from browser?
[英]Programatic code modification (e.g. variable extraction) in Java
我知道可以使用Reflection做一些不錯的事情,例如調用方法或更改字段的值。 但是,是否可以在運行時和以編程方式進行更大量的代碼修改?
例如,如果我有一個方法:
public void foo(){
this.bar = 100;
}
我可以編寫一個程序來修改此方法的內在特性,注意到它為字段分配了一個常量,並將其轉換為以下內容:
public int baz = 100;
public void foo(){
this.bar = baz;
}
也許Java並不是真正用於執行此類操作的語言-否則,我願意接受有關語言的建議,這些建議將允許我基本上以這種方式重新解析或檢查代碼,並能夠如此精確地對其進行更改。 我可能在這里做夢,所以請告訴我是否也是這種情況。
只是添加一個朋友的建議-Apache Commons的BCEL看起來很棒:
http://commons.apache.org/bcel/manual.html
字節碼工程庫(Apache Commons BCEL™)旨在為用戶提供一種方便的方法來分析,創建和操作(二進制)Java類文件(以.class結尾的文件)。 類由對象表示,這些對象包含給定類的所有符號信息:特別是方法,字段和字節碼指令。 這樣的對象可以從現有文件中讀取,可以通過程序(例如,運行時的類加載器)進行轉換,然后再次寫入文件中。 一個更有趣的應用程序是在運行時從頭開始創建類。 如果您想了解Java虛擬機(JVM)和Java .class文件的格式,則字節碼工程庫(BCEL)也可能很有用。
可以公平地說,Java並不是出於這個目的而設計的,但是您可以潛在地做到這一點。 如何以及何時取決於練習的最終目的。 有兩個選擇:
在源代碼級別,可以使用Java Compiler API將任意代碼編譯成類文件(然后可以加載)。
在字節碼級別,您可以編寫一個安裝ClassFileTransformer的代理,以在加載類時“動態”更改類。 在實踐中,如果這樣做,您可能還可以利用BCEL(字節碼工程庫)之類的庫來簡化類的操作。
你的意思是這樣嗎?
String script1 = "println(\"OK!\");";
eval( script1 );
script1 += "println(\"... well, maybe NOT OK after all\");";
eval( script2 );
輸出:
OK!
OK!
... well, maybe NOT OK after all
...使用Java腳本擴展。 Groovy之類的事情可能會讓您做自己想做的事情。 我已經編寫了一個腳本擴展,可以自己幾乎無縫地通過反射與Java集成。 如果您對詳細信息感興趣,請與我聯系。
您想研究程序轉換系統(PTS) ,它提供了用於在源代碼級別解析和轉換語言的常規工具。 PTS提供了重寫規則,實際上使用目標語言的表面語法說:“如果看到此模式,則用該模式替換”。 這是使用完整的解析器完成的,因此重寫規則實際上是根據語言語法而不是文本執行的; 與基於正則表達式的工具不同,此類重寫規則顯然不會嘗試在注釋中修改類似代碼的文本。
我們的DMS軟件再造工具包就是其中之一。 它不僅提供常規的解析,AST構建和prettyprinting(再現帶有注釋的可編譯源代碼),而且還支持符號表以及控制和數據流分析。 幾乎所有有趣的轉換都需要這些。 DMS還具有各種Java語言以及許多其他語言的前端。
存在字節碼轉換器是因為它們易於構建。 “解析”字節碼非常容易。 當然,您不能使用字節碼轉換器進行永久的源更改,因此它的用途要少得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.