Java無(wú)可匹敵的變身裝備,鋼鐵俠客的絕密味道
我討厭寫一些業(yè)務(wù)代碼,不僅僅因?yàn)樗鼈兊脑家鈭D不是我設(shè)計(jì)的,成功了是產(chǎn)品的功勞,失敗了代碼要背鍋。一個(gè)重要的原因,就是重復(fù)的代碼太多,一個(gè)復(fù)雜的業(yè)務(wù)邏輯要找到它的Bug,也要下一番“苦力”。這里說(shuō)的真的是苦力,而不是腦力,說(shuō)明了大部分是低劣的重復(fù)勞動(dòng)。
所以隨著在項(xiàng)目中有了話語(yǔ)權(quán),我會(huì)特別善待這些可憐的同學(xué)們。一個(gè)問(wèn)題,直到發(fā)現(xiàn)的時(shí)候,才發(fā)現(xiàn)它的低級(jí),但中間的曲折,很少有人能看到,一個(gè)非技術(shù)出身的管理者對(duì)此就很難理解。職位越是高,就越關(guān)注整體的目標(biāo)達(dá)成,對(duì)個(gè)體的感受卻關(guān)注的很少,這不是一個(gè)好的現(xiàn)象。千里之堤,潰于蟻穴。普通研發(fā)的整體水平代表了公司的競(jìng)爭(zhēng)力。哦哦哦,我竟然違背了精英主義論調(diào)。
扯遠(yuǎn)了。下面介紹幾個(gè)開(kāi)發(fā)中常用的工具包,可以在Java源文件、語(yǔ)法樹(shù)、字節(jié)碼之間進(jìn)行轉(zhuǎn)換。用好了它們,不僅僅能實(shí)現(xiàn)一些黑科技,還能大大提高我們的生產(chǎn)力。
1、JavaPoet
有時(shí)候,我們要做一些代碼生成工具,需要生成一些Java類源文件。如果使用字符串去拼接的話,很容易拼的亂七八糟。為了解放雙手,就可以使用工具JavaPoet進(jìn)行方法或者代碼塊的構(gòu)建。它還提供了占位符等一系列方便的操作,使得你生成的代碼優(yōu)美可讀,清脆爽口。
特別在寫一些框架的時(shí)候,可以將一些非常臟、非常累的活兒交給它。
代碼示例。
MethodSpec main = MethodSpec.methodBuilder("main") .addStatement("int total = 0") .beginControlFlow("for(int i=0;i<10;i++)") .addStatement("total +=i;") .endControlFlow() .build();
2、JavaCC
JavaCC是一個(gè)語(yǔ)法生成器和語(yǔ)法分析器,可以通過(guò)讀取一個(gè).jj(它是雞雞我是姐姐)描述文件來(lái)生成一個(gè)Java文件。聽(tīng)起來(lái)和JavaPoet一樣,但它是語(yǔ)法層面的,過(guò)程是翻譯而不是“構(gòu)造”,和我們學(xué)習(xí)的編譯原理是一個(gè)層面的東西。而且JavaCC生成的文件一般是不可讀的,誰(shuí)讓它和yacc以及l(fā)ex比較像呢。
如果你想要自定義一些表達(dá)式,或者做一個(gè)特殊格式的解析器,你可能會(huì)用到它。
與此類似的還有ANTLR。應(yīng)用方面,Velocity和FreeMarker都使用JavaCC作為語(yǔ)法解釋器;Hibernate則使用ANTLR作為HQL的語(yǔ)法解釋器。
不過(guò)我還是更喜歡Ragel(不是Java的)多一些。對(duì)于這些場(chǎng)景來(lái)說(shuō),文件生成以后就不再依賴這些工具了,還是高效和好用更重要。
2、Javaparser
上面是通過(guò)語(yǔ)法樹(shù)生成Java文件(或者其他文件),Javaparser是通過(guò)Java文件生成語(yǔ)法樹(shù)(AST),然后基于這棵語(yǔ)法樹(shù)進(jìn)行Java代碼的分析和修改。注意,它可以直接再根據(jù)語(yǔ)法樹(shù),反向生成Java文件哦。
根據(jù)這棵語(yǔ)法樹(shù),你可以直接分析一個(gè)獨(dú)立的Java文件,即使這個(gè)Java文件亂七八糟,不能通過(guò)編譯,不用在運(yùn)行時(shí)使用反射等功能。配合JavaPoet可以去做一些非常有意思的功能。比如,Javaparser提取Java文件的注釋或者注解,然后通過(guò)JavaPoet生成一些自動(dòng)文檔(Swagger),或者進(jìn)行測(cè)試用例的自動(dòng)填充。
除了這些,Javaparser可以規(guī)定十分嚴(yán)格的語(yǔ)法格式,所以使用它做一個(gè)代碼審查工具,甚至是做一些代碼依賴分析,也是可以的。
4、Lombok
其實(shí)這只是個(gè)輔助開(kāi)發(fā)工具,應(yīng)該有很多研發(fā)用起來(lái)了,它可以顯著的減少代碼量。讓我們擺脫惱人的get、set、hashCode、equals,甚至log等。
Lombok其實(shí)部分上和上面說(shuō)到的Javaparser類似,不過(guò)它是JDK層面的。
在javac將Java文件解析成抽象語(yǔ)法樹(shù)之后(AST),Lombok則根據(jù)自己的注解處理器,動(dòng)態(tài)的修改AST,增加新的節(jié)點(diǎn)代碼。然后,生成我們最終的字節(jié)碼。
這個(gè)技術(shù),是由javac的注解API來(lái)實(shí)現(xiàn)的(JSR-269),可以讓javac在編譯期去干一些事情。
JDK做的工作,遠(yuǎn)比我們表面上用到的那些多的多。
5、ByteBuddy
上面幾個(gè)工具都是把一些其他方式的代碼轉(zhuǎn)化為Java源文件,這些Java源文件還需要經(jīng)過(guò)編譯這道工序,才能夠被真正使用。
ByteBuddy可以更進(jìn)一步,直接動(dòng)態(tài)生成Java類。對(duì),就是直接加載在元空間的那種,在程序運(yùn)行期間就可以動(dòng)態(tài)的對(duì)class進(jìn)行更改。不需要曲徑通幽,直達(dá)目的。
它的底層是ASM,所以ByteBuddy是可以直接修改字節(jié)碼的,是一種字節(jié)碼增強(qiáng)工具。
于此類似的工具還有JAVASIST、CGLiB等。
如果你在做一些代理類的工作,或者做一些APM等,想要實(shí)現(xiàn)類似Aspectj之類的功能,再或者類似Arthas那樣的故障排查工具,那這些工具正適合。
End
以上幾個(gè)工具包,有些是比較偏門的,但它們完成的功能卻非??犰?。不僅酷炫,而且非常有用。在領(lǐng)導(dǎo)們頻繁開(kāi)會(huì),使用各種方法論探討怎么管理文檔,怎么自動(dòng)化,怎么代碼審查的時(shí)候,你就已經(jīng)把功能完成了。
別告訴他們!