最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

學習筆記2:JavaParser-結構化Java代碼解析修改器

2023-04-06 20:54 作者:帽子太卡呢  | 我要投稿

1.學習JavaParser的動機

?

我學習使用JavaParser的動機,是因為在開發(fā)項目時,面對項目重構,對每次都需要面對一大堆代碼做幾乎相同的修改感覺非常頭疼,之前兩次動不動就動員了一大波人改了幾天的代碼給我留下了巨量心理陰影。IDE提供的重構很多時候只能針對同一個類的Name,相同Field或者Method進行處理,而現有的項目代碼經常有使用相同設計規(guī)則,調用方式相似,但是class基本完全無關的代碼,對這些代碼進行重構會很頭疼,例如將一批類型不同但是必須分開存放的handler從一個class轉存到它的一個成員對象里面,或者為一批對象添加工廠構造方法/clone方法,并且因為效率問題而不允許使用運行時反射的方法進行處理。所以我稍微找了一下找到了JavaParser這個工具。

JavaParser是一個java語言的句法分析器,可以將已有的java代碼拆解為代碼句法解析樹,并且允許通過修改樹的方式對代碼進行批量修改,因此通過JavaParser可以做到獲取代碼的解析信息,對代碼進行批量檢查,修改代碼結構或者內容等功能。

我覺得JavaParser存在的不足:使用復雜,文檔不好查詢,批量添加代碼需要添加一大堆Statement和Expression,相對于JavaPoet算比較麻煩的東西了,所以如果需求是創(chuàng)建從零開始的java文件,我覺得肯定還是優(yōu)先使用JavaPoet。

另外被JavaParser修改過的代碼,會被強制格式化成其預設的Java格式,對于我這種幾乎無條件要求大括號換行的人來說簡直是邪教,但是看了源代碼后發(fā)現幾乎只有修改源代碼重打jar包或者Override原始方法時復制粘貼其原始方法微調才能實現了。

不過相對而言,因為JavaParser使用起來相對復雜,很多時候又根本查不到別人有類似需求,找不到別人的做法,自己只能對著JavaDoc無能狂怒,雖然大體上最后還是找到了解決方法,但是我總之需要為自己記錄一下JavaParser的使用經驗,為未來的自己提供學習記錄。

?

JavaParser的基礎是JavaCC,一種基于java的句法解析工具,可以自定義句法解析樹來對輸入字符串進行解析,我讀研的時候項目組正好也是使用的JavaCC開發(fā)的項目,但是當時我覺得這玩意兒文檔又少又難用,吐槽了很多,還以為其實沒很多人用這個功能,這次發(fā)現救我狗命的JavaParser也是基于JavaCC開發(fā)的,讓我略顯意外(捂臉)

?

2.JavaParser的導入

可以通過github下載,也可以通過maven導入。如果在git上下載似乎需要自行編譯成jar包。(當然也可以順路改代碼定制化,嗯)

項目地址:https://github.com/javaparser/javaparser/

?

3.JavaParser的順序遍歷

JavaParser解析java文件一般提供兩種方式處理解析結果,一種方式是直接按照解析樹的順序進行順序遍歷,另一種方式是通過Visitor訪問者模式對需要的表達式進行訪問處理。本節(jié)說明順序遍歷的方法。

?

JavaParser會將單個java文件解析成語法結構樹,例如class下定義了哪些field和method,然后method里有哪些代碼,單行代碼的結構又可以細分為哪些表達式和哪些表達式的嵌套或者運算符計算等。以下代碼為一個簡單的示例,為指定的class文件添加一個clone方法,這個clone方法不使用默認的方法進行clone,而是會分別基于對象的final與否,創(chuàng)建一個new對象并將所有final對象作為構造函數輸入參數,將非final參數進行賦值操作。

實際計算效率肯定不如原生native的clone方法快,這里主要是用于演示。

?

?

可以看出,核心代碼片段在body.addStatement()函數,這個函數不能自由地加入string來書寫java片段,而必須通過嚴格地按照java解析樹一樣的結構來加入一段java代碼解析單元。所以添加一小段代碼的操作可能都需要花不少功夫,查個半天javaDoc來找需要的Expr子類(我真的找了很久,文檔說的也不清楚根本看不懂這些Expr都是啥意思,找到FieldAccessExpr花了老半天功夫...github的readme里提供的樣例太淺不能作為參考,國內搜索凈是復讀機,真的讓我頭疼了挺久)

?

?

4. JavaParser的訪問者模式遍歷

上述代碼中可以看到,以順序方式訪問JavaParser的解析樹是一個比較麻煩的事情,如果需求修改的代碼對象可以用很簡單的邏輯找到,使用順序遍歷方式就要先寫一堆代碼有點煩。JavaParser還推出了通過訪問者模式進行代碼修改的方法,以下列代碼為例,可以將一個指定包內的已有的obj.func()重構為obj.subObj().func()函數,通過訪問者模式直接找到“函數調用”類型的表達式,直接進行修改。

?

?

訪問者模式適用于原始數據結構十分固定而復雜,需要進行邏輯處理的對象經?;谠紨祿Y構中特定類型數據的情況。具體的設計模式可以另外查詢。

另外,JavaParser的代碼printer部分也使用了訪問者模式,JavaParser生成java文件的代碼結構是硬編碼在printer方法里的,如果希望其按照自己期望的格式輸出java文件(例如大括號分行黨),也需要通過訪問者模式繼承DefaultPrettyPrinter來實現。

?

5.JavaParser的個人總結

?

JavaParser對代碼可以進行解析,修改重構,輸出代碼結構樹。嚴格結構的代碼樹可以以特定想要的邏輯進行檢查或者修改,但是代價是修改成本往往比直接輸出字符串要困難很多,不會的時候查個半天文檔還要作測試代碼才會用,維護過程也需要更多閱讀才能理解。大體上我是不愿意用JavaParser從零開始生成代碼的,感覺真的很煩人。與之相對應,如果有明確的對代碼批量修改的需求時,JavaParser就會很救命,可以從無窮無盡的手動修改代碼中解放出來,從這一點來說我是可以給好評的。


學習筆記2:JavaParser-結構化Java代碼解析修改器的評論 (共 條)

分享到微博請遵守國家法律
潢川县| 武胜县| 大城县| 台江县| 崇礼县| 靖远县| 西青区| 轮台县| 鄂托克前旗| 青浦区| 黄大仙区| 桓台县| 琼中| 荆门市| 青州市| 潼关县| 光山县| 尚志市| 朔州市| 张家川| 永吉县| 门源| 商都县| 工布江达县| 自治县| 福州市| 高邑县| 钟山县| 关岭| 陇川县| 新巴尔虎右旗| 喀什市| 邵武市| 拉萨市| 白山市| 饶平县| 阿图什市| 溧水县| 安平县| 天长市| 河池市|