這是一個java代碼動態編譯工具,也就是可以把String形式的java代碼實時地編譯爲字節碼的工具;java
「動態編譯」工具,其實自jdk1.6發佈以來,應該出現過不少,不過kan-java的特色在於 —— 就像它的名字同樣 —— 能夠選擇性地砍掉任意語言特性;git
也就是說 —— 這是一個能夠在動態編譯java代碼的同時,對java語言語法作裁剪的動態編譯工具。程序員
經過下面這個例子能夠看出「裁剪」指的是什麼意思:github
// 禁止帶標籤的continue語句 void testLabeledContinue(){ def kan = new KanJava(Feature.labeledContinue) def srcs = [] srcs << new JavaSourceFile("TestLabeledContinue.java", "kanjava.test", readContent("testLabeledContinue/TestLabeledContinue.src")); def rst = kan.checkAndCompile(srcs) assertTrue !rst.isSuccess() assertTrue rst.errMsg != null assertTrue rst.classes == null println rst.errMsg }
上述groovy代碼建立了一個KanJava編譯工具實例, 並指明想要砍掉labeledContinue特性(即帶標籤的continue語句)
其中readContent方法的返回結果以下:編程
package kanjava.test; public class TestLabeledContinue { public static void main(String... args) { for(int i=0;i<10;i++){ if(i == 5) continue; } label: while(true){ if(true) continue label; } } }
上述代碼包含2個continue語句:第一個不帶標籤而第二個帶標籤
最終輸出結果以下:api
Error at row: 10, col: 22, reason: Continue statements with labels are not allowed.
即「帶標籤的continue語句」已被禁止了,在編譯過程當中發現這種語句即會報錯, 其核心功能,概念上講就是這麼簡單。oracle
擁有一個裁剪版本的java,這有怎樣的應用場景?框架
目前最直接的答案是"高性能的內部DSL"jvm
即當我須要一個語法上很是接近普經過程式編程語言的DSL,但卻又不想或以爲不必本身從頭實現一個(外部DSL)的時候,就能夠考慮以某種現成的過程式通用編程語言爲藍本,經過裁剪其語法達到目的;
而當這種「現成的過程式通用編程語言」被選擇爲java時,kan-java出場的時刻就到了, 試想一下,下面這樣「砍」會砍出來什麼效果? ——maven
private static final KanJava kanJava = new KanJava(Feature.assertion, Feature.doWhileLoop, Feature.forLoop, Feature.labeledBreak, Feature.labeledContinue, Feature.nestedClass, Feature.whileLoop);
相信全部java程序員均可以猜到:你將獲得一個「沒有assert語句、沒有do-while循環、沒有for循環、沒有帶標籤的break、沒有帶標籤的continue、沒有嵌套類、沒有while循環」的 —— java.
P.S. 若是你還堅信它是java的話 :)
而這些"內部DSL"最終將被編譯成字節碼運行,所以也有了高速運行的基礎;
因此說kan-java可以成爲「利用java實現高性能的內部DSL」的強大工具。
上面示例中的這種「砍」法並不誇張,這是從現實中的使用案例中截選出來的。
kan-java提供的api可以將「砍語法」和「編譯爲字節碼」拆分爲兩個步驟;
這使得你能夠 —— 好比說 —— 在用戶輸入的時候禁掉'import語句',而實際編譯的時候能夠正常插入import語句後再編譯, 相信這種功能會頗有用;
更廣泛意義地講,kan-java實際上提供了一套"java語言語法靜態處理框架", 在此框架之上,「砍」語法其實只是冰山一角 —— 由於你還能夠用它來「砍用法」,好比你並不想徹底禁掉import語句,但但願禁止import一些特定的類;
再好比你不想徹底禁止用戶new對象,但你可以作到不讓用戶new特定的對象...
凡是可以出如今代碼當中的任意結構,均可以被控制。
所以能夠說,被髮布出來的kan-java庫只是一個小小的核心,其更加廣闊的應用場景還有待猿們繼續擴充...
有沒有更加「高級(黑)」的話題? 固然有;由於在kan-java提供的這套框架之上不只限於能「砍」,它還能「加」...
不過目前這個庫的主要目的仍是提供一套「基於java的內部DSL構建工具」,其它的什麼「用kan-java作源碼加強」,什麼「用kan-java把java編譯到GPU上」這些黑科技就暫不展開了 :)
最重要的事情老是最後才說...
目前kan-java所支持的java基礎語法是1.6的,也就是說,你使用kan-java來「砍」語法的時候,是以java 1.6爲基礎來砍的
不過這並不影響kan-java庫被放到更高版本的java環境中使用(above v1.6), 起碼大多數狀況下是ok的;不過,若是真的遇到問題,仍是最好能從源碼編譯一份對應當前java版本環境的kan-java庫(由於kan-java在實現上使用了com.sun包下的一些類, 這些類並不徹底保證在不一樣版本java之間的兼容)
一樣由於kan-java使用了com.sun包下的類,我也只能假定kan-java只能在oracle hotspot jvm上運行
目前開放的可被「砍」的功能,只是源於目前我我的在實際項目中的須要而已;確定還有更多可能的「花式砍法」,若是但願有,能夠提出來,有興趣的咱們能夠共建
使用kan-java時,需確保tools.jar也在classpath中
按道理講,除了java標準庫,kan-java是不須要依賴任何第三方庫的,不過項目中出現了對groovy-all的依賴,這僅僅是由於我想實踐一把"java和groovy混編開發模式"的任性而已,不要太在乎 :)
目前的發佈版本爲v0.1, maven依賴爲:
<dependency> <groupId>com.github.pfmiles</groupId> <artifactId>kan-java</artifactId> <version>0.1</version> </dependency>