'kan-java' 就是 '砍-java'

这是一个java代码动态编译工具,也就是能够把String形式的java代码实时地编译为字节码的工具;

“动态编译”工具,其实自jdk1.6发布以来,应该出现过很多,不过kan-java的特点在于 —— 就像它的名字一样 —— 可以选择性地砍掉任意语言特性;

也就是说 —— 这是一个可以在动态编译java代码的同时,对java语言语法做裁剪的动态编译工具。

通过下面这个例子可以看出“裁剪”指的是什么意思:

// 禁止带标签的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 != nullassertTrue rst.classes == nullprintln 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语句:第一个不带标签而第二个带标签
最终输出结果如下:

Error at row: 10, col: 22, reason: Continue statements with labels are not allowed.

即“带标签的continue语句”已被禁止了,在编译过程中发现这种语句即会报错, 其核心功能,概念上讲就是这么简单。

这能有什么用?

拥有一个裁剪版本的java,这有怎样的应用场景?

目前最直接的答案是"高性能的内部DSL"

即当我需要一个语法上非常接近普通过程式编程语言的DSL,但却又不想或觉得没必要自己从头实现一个(外部DSL)的时候,就可以考虑以某种现成的过程式通用编程语言为蓝本,通过裁剪其语法达到目的;
而当这种“现成的过程式通用编程语言”被选择为java时,kan-java出场的时刻就到了, 试想一下,下面这样“砍”会砍出来什么效果? ——

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>

原文链接:https://github.com/pfmiles/kan-java


kan-java, 一个能裁剪语法特性的java动态编译工具相关推荐

  1. Kotlin 与 Java 8 的重要新特性以及 Java 9、10 的发展规划

    Java 8可谓是自Java 5以来最具革命性的版本了,她在语言.编译器.类库.开发工具以及Java虚拟机等方面都带来了不少新特性.我们来一一回顾一下这些特性. 一.Lambda表达式 Lambda表 ...

  2. java 模块化_Java 9 新特性 - 模块化 - Java 技术驿站-Java 技术驿站

    Java 9 最大的特性就是模块化 ( Module ) 了.本章,我们就对这个 模块化 进行一些简单的讲解,包括 Java 9 模块化的概念.如何实现.如何使用等 对于 Java 9 来说,模块化 ...

  3. Java系列 – 用Java8新特性进行Java开发太爽了(续)

    本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome-2/ 前言 上周, 我们谈论了关于Ja ...

  4. java 1.7的新特性_[Java]  JDK 1.7版本的 新特性

    在网上看到一些jdk1.7的新特性,现将我觉得比较实用的记录于下: (1)switch中可以使用字串了 String s = "test"; switch (s) { case & ...

  5. Java系列 - 用Java8新特性进行Java开发太爽了

    本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome/ 前言 从开始写博客到现在已经过去3个 ...

  6. Java 17的这些新特性,Java迈入新时代

    前言 2021年9月14日Java 17发布,作为新时代的农民工,有必要了解一下都有哪些新东西. Java 17是Java 11以来又一个LTS(长期支持)版本,Java 11 和Java 17之间发 ...

  7. java一个引用多大_为什么Java 8为方法引用引入了一个新的“::”运算符?

    在Java 8中,使用::运算符完成引用. 例如 // Class that provides the functionality via it's static method public clas ...

  8. java实现线段裁剪算法,多边形裁剪算法java

    Weiler-Atherton 任意多边形裁剪 Sutherland-Hodgeman 算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及 任意多边形窗口(含凹多边形窗口)的裁剪.Weiler ...

  9. 1 Java基础后端-基础语法

    1 Java基础后端-基础语法 编程语言介绍 java介绍 文章目录 1 Java基础后端-基础语法 1.1. 计算机语音发展 1.2. Java和C比较 1.3. windows常用DOS 1.4. ...

最新文章

  1. javascript图片懒加载与预加载的分析
  2. python程序实例电话本-利用Python电话本小程序!这波操作你给几分?
  3. 【PC工具】离线地图图片地图瓦片下载神器map-download地图下载器
  4. iOS Hacker 越狱后开发和逆向工具准备
  5. finalize方法_final,finally,finalize三者的含义和区别
  6. 聊聊ExecutorService的监控
  7. 鱼塘钓鱼(信息学奥赛一本通-T1373)
  8. 手撸一款精美的水波气泡
  9. python能做什么项目-适合Python 新手的5大练手项目,你练了么?
  10. (十六)K-Means聚类
  11. php出库单编号怎么编,求大神帮忙写VBA,出库单自动保存到明细,自动编号
  12. C# Newtonsoft JArray排序
  13. 网管员不得不关注的九大热门网络技术
  14. ajax批量上传数据,Ajax上传数据和上传文件(三种方式)
  15. 解决百度网盘超过4G限制,
  16. 4K工业级高清4进1出HDMI自动USB KVM多电脑切换器(MT-HK401)
  17. php 图片消除锯齿,ps如何消除边缘锯齿
  18. 【AIOT】2-2 物联网案例分享
  19. 如何在Mac上查找WiFi密码并在iPhone上共享它?
  20. 转至老熊三分地--inside sqlplus prelim

热门文章

  1. Verilog实现---IEEE标准的单精度浮点乘法器
  2. php获取蓝凑云文件列表,【PHP】利用蓝奏网盘做个人小文件网盘和获取真实下载地址...
  3. 默认google浏览器打不开链接(点击超链接没有反应)
  4. java如何调用驱动程序_使用Java驱动程序查找和上载
  5. halcon图像灰度操作
  6. MySQL——数据库基本操作(教程)
  7. 软件开发中,站立会议的必要性
  8. 牛客小白月赛32--C消减整数、E春游(贪心)
  9. android p2p 连接服务器上,当通过Wi-Fi P2P使用网络服务发现时无法连接到Android设备每个人都可以使用网络服务发现...
  10. tick_params()--matplotlib