您现在的位置是:首页 > 文章详情

🔥 Java 动态编译神器 Janino 和 Liquor 差别

日期:2024-09-24点击:198

如果你只要 Java7 及以下的语法支持,建议 Janino。如果要你想更全的 Java8、Java11、Java17、Java21 等语法,可以选 Liquor。

1、它们相同的地方

  • 提供的相似的能力接口
接口 Janino Liquor
动态编译器 SimpleCompiler DynamicCompiler
表达式评估器 ExpressionEvaluator LiquorEvaluator (Exprs)
脚本评估器 ScriptEvaluator LiquorEvaluator (Scripts)
  • 都是 Java 语言(语法)的动态应用。生成的字节码都可以完全访问 JRE,可能要注意安全的控制。

2、细节区别处

  • Janino 基于自已的编译能力实现。
    • 支持 Java7 及以下语法。
    • 单次编译性能,更好。
    • 支持命令行编译。
    • 提供更丰富的功能。比如代码分析器,等。
  • Liquor 基于 JDK 自带的编译能力实现。
    • 支持 Java8、Java11、Java17、Java21 等语法(由运行时版本决定)。
    • 单次编译性能,差些。
    • 不支持命令行编译。可用 javac 命令。

3、具体差异 - 动态编译器

动态编译器的性能,基本上可以按“次”计量。次数越多,费时越多。尽量把可知代码,合在一起编译(次数,越少越好)。

  • Janino
 public class JaninoTest { public static void main(String[] args) throws Exception { //此类,不可以复用(可以通过别的方式,实现多类一起编译) SimpleCompiler compiler = new SimpleCompiler(); String className = "HelloWorld"; String classCode = "public class HelloWorld { " + " public static void helloWorld() { " + " System.out.println(\"Hello, world!\"); " + " } " + "}"; //只能单个编译 compiler.cook(classCode); //再 cook ,则会异常 Class<?> clazz = compiler.getClassLoader().loadClass(className); clazz.getMethod("helloWorld").invoke(null); } } 
  • Liquor
 public class LiquorTest { public static void main(String[] args) throws Exception{ //可以复用(可以,不断的增量编译) DynamicCompiler compiler = new DynamicCompiler(); String className = "HelloWorld"; String classCode = "public class HelloWorld { " + " public static void helloWorld() { " + " System.out.println(\"Hello, world!\"); " + " } " + "}"; //可添加多个源码 compiler.addSource(className, classCode); compiler.build(); //构建后,仍可添加不同类的源码再构建 Class<?> clazz = compiler.getClassLoader().loadClass(className); clazz.getMethod("helloWorld").invoke(null); } } 

4、具体差异 - 表达式评估器

比较 Janino Liquor
缓存 无(可以自己包装) 有二级缓存(类加载器缓存,编译结果缓存)
体验 每次要重新构建 方便
性能 单次更好 缓存命名时,非常好(接近原始 Java 代码性能)
  • Janino
 public class JaninoTest { public static void main(String[] args) throws Exception { //每次要新实例化 ExpressionEvaluator ee = new ExpressionEvaluator(); ee.cook("3 + 4"); System.out.println(ee.evaluate()); } } 
  • Liquor
 public class LiquorTest { public static void main(String[] args) throws Exception { //单例,可复用,线程安全 System.out.println(Exprs.eval("3 + 4")); } } 

5、具体差异 - 脚本评估器

比较 Janino Liquor
缓存 无(可以自己包装) 有二级缓存(类加载器缓存,编译结果缓存)
体验 每次要重新构建 方便
性能 单次更好 缓存命名时,非常好(接近原始 Java 代码性能)
  • Janino
 public class JaninoTest { public static void main(String[] args) throws Exception { //每次要新实例化 ScriptEvaluator se = new ScriptEvaluator(); se.cook("System.out.println(\"hello word\");"); se.evaluate(); } } 
  • Liquor
 public class LiquorTest { public static void main(String[] args) throws Exception { //单例,可复用,线程安全 Scripts.eval("System.out.println(\"hello word\");"); } }
原文链接:https://www.oschina.net/news/313230
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章