这是一个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>