2011-04-21 164 views
4

我正在尋找一種方法,根據類中定義的字段自動生成現有Java源代碼文件中的新方法的源代碼。自動生成Java源代碼

從本質上說,我期待執行下列步驟:通過源代碼中定義的所有字段

  1. 讀取並解析SomeClass.java
  2. 迭代
  3. 添加源代碼方法someMethod()
  4. 保存SomeClass.java(理想情況下,保留現有代碼的格式)

什麼工具和技術最適合完成這個工作?

編輯

我不想在運行時生成的代碼;我想擴充現有的Java 源代碼

+0

或者,您可以編寫一個更好的界面。代碼生成是非常少見的,因爲大部分時間它可以被更好的界面取代。例如,你可以讓'SomeClass.java'實現一個提供'someMethod()'的接口,或者你可以擴展一個抽象類,從而爲你提供所需的'someMethod()'實現。如果'someMethod()'在任何地方都是一樣的,那麼你也可以添加一個獨立的接口和實現,以便在你希望能夠使用它的任何地方使用它。 – ThePyroEagle 2016-05-01 14:58:10

回答

2

使用自動生成的代碼修改相同的java源文件是維護的噩夢。考慮生成一個新的類來擴展你當前的類並添加所需的方法。使用反射從用戶定義的類中讀取併爲自動生成的類創建速度模板。然後爲每個用戶定義的類生成其擴展類。在您的構建生命週期中集成代碼生成階段。

或者您可以使用'字節碼增強'技術來增強類而不必修改源代碼。

更新:

  1. 混合自動生成的代碼總是有人提出將來修改它只是調整一個小行爲的風險。這只是下一次構建的問題,當這種變化將會丟失。
  2. 您將不得不完全依靠自動生成源代碼的評論來阻止開發人員這樣做。
  3. 版本控制 - 假設您更新someMethod()的模板,現在所有源文件的版本都會更新,即使源更新是自動生成的。你會看到多餘的歷史。
+2

謝謝。我的想法是,注入自動生成的代碼比字節碼增強的「隱形魔術」更清晰,更易維護,但我會對我提議的方法的可維護性的具體問題感到好奇 – 2011-04-21 15:04:51

+0

我把它作爲一個新問題提出:http ://stackoverflow.com/questions/5746099/automatic-source-code-generation-good-idea-or-potential-nightmare – 2011-04-21 15:17:06

2

您可以使用cglib在運行時生成代碼。

+0

+1:和Objectweb ASM – 2011-04-21 14:51:44

+0

謝謝,但尋找*源代碼*代 – 2011-04-21 14:55:56

1

遍歷字段並定義someMethod是一個非常模糊的問題陳述,所以很難給你一個非常有用的答案,但是Eclipse的重構支持提供了一些優秀的工具。它會給你構造函數初始化一組選定的成員,它也會爲你定義一個toString方法。

我不知道其他someMethod()是你想要考慮的,但是有一個開始。

4

看一看Java發射模板。它們允許您使用標記語言創建Java源文件。這與您如何使用腳本語言來吐出HTML除非您吐出可編譯的源代碼類似。 JET的語法與JSP非常相似,因此不太難處理。然而,這可能是你想要完成的事情的矯枉過正。這裏有一些資源,如果你決定走這條路:

1

我會非常謹慎的注入生成的代碼轉換成包含手寫代碼的文件。應該將手寫代碼檢入到版本控制中,但生成的代碼不應該是;代碼生成應作爲構建過程的一部分來完成。您必須構建構建過程,以便爲每個文件創建一個臨時副本,將生成的源代碼注入其中,並編譯結果,而不觸及開發人員處理的原始源文件。

+0

謝謝!我正在尋找爲模型類生成持久性代碼,只有在類代碼本身發生更改時纔會更改。 (不幸的是,在Java中沒有'partial'類) – 2011-04-21 15:36:18

+0

@Jen,它是否有意義使用反射,可能通過模型​​類上的註釋指導,而不是實際修改每個需要被持久化的類? – Wyzard 2011-04-21 15:40:35

+1

是的,這也是一種有效的方法,但我正在尋找a)更高的性能和b)更高的代碼清晰度(我的想法是,通過閱讀生成的代碼比解決問題更容易瞭解發生的事情不同的約定/註釋) – 2011-04-21 15:44:53

11

你想要的是一個Program Transformation系統。

好的分析器爲您所關心的語言提供解析器,構建代表解析代碼的程序的AST代碼,爲您提供對AST進行分析和修改的權限,並且可以從AST中重新生成源代碼文本。你關於「掃描字段」的評論只是代表程序的AST的一種遍歷。對於你產生的每一個有趣的分析結果,你想要改變AST,也許在其他地方,但在AST中。 當所有的chagnes都被創建後,您想要使用註釋重新生成文本(如最初輸入的那樣,或者如您在新代碼中構建的那樣)。

有幾種工具可以專門用於Java。

Jackpot提供了一個解析器,構建AST,並讓您編寫Java過程來完成您想要的樹。上行:概念上簡單。下行:你寫了更多的Java代碼來繞過/砍樹,比你想象的要多。積寶只適用於Java。

StrategoTXL解析代碼,構建AST,並讓您編寫「surce-to-source」轉換(使用目標語言的語法,例如本例中的Java)來表示模式和修復。額外的好消息是:您可以將任何您喜歡的編程語言定義爲要處理的目標語言,並且這兩種語言都具有Java定義。但它們在分析上很薄弱:通常你需要符號表和數據流分析來真正做出你需要的分析和改變。他們堅持認爲的一切是一個重寫規則,無論是否幫助你;這有點像堅持你只需要一把工具箱中的錘子;畢竟,一切都可以像一個釘子對待,對嗎?

我們DMS Software Reengineering Toolkit允許abitrary目標語言的定義(並且具有many predefined langauges including Java),包括西洋陸軍棋,TXL,累積獎金, 的程序能力的所有的源極 - 到 - 源極轉換功能,並且另外提供了符號表,控制和數據流分析信息。編譯器的傢伙告訴我們,這些東西是必要的,建立強大的編譯器(=「分析+優化+精」),它是代碼生成系統來說也是一樣。對於完全相同的原因。使用這種方法,您可以生成代碼並在您已掌握知識的情況下對其進行優化。一個例子,類似的系列化的想法,是產生特定XML DTD的快速XML讀者和作家;我們已經使用DMS for Java和COBOL完成了這項工作。

DMS已用於讀取/修改/寫入多種源文件。在這篇技術文章中,可以找到一個很好的例子,可以讓你明白這個想法,該文章展示瞭如何修改代碼以插入儀表探針:Branch Coverage Made Easy。 使用相同的想法可以在How to transform Algebra找到一個更簡單但更完整的例子,定義一個適用於它的任意顏色和變換。

1

Antlr真的是一個非常好的工具,可以非常方便地將Java源代碼轉換爲Java源代碼。