Java内存代码的动态编译(运行时编译)
发表于2019-12-18,长度1215,
210个单词,
3分钟读完
Java 可以在运行时动态编译并执行代码,一种代码是本来就可以在虚拟机上跑的字节码,如Java、Scala、groovy等,另一类是Java特意提供了执行引擎的JavaScript。这里看一下如何进行动态编译。
JS引擎
据说Java以后会删掉JS引擎,所以最好不要依赖
这个很简单:
String original = "var res = 0.0; if (#1 >= 1000) { res = #1 * 0.1 ;} else if (#1 >= 100) {res = #1 * 0.01} ; res ;";
String script = original.replace("#1", "100");
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
log.info("结果 {}", engine.eval(script));
} catch (ScriptException e) {
e.printStackTrace();
}
历史上,Java提供过几个JS引擎的实现,现在Nashorn是性能最好、JS特性支持最广泛的一个。
Groovy 引擎
groovy的执行方式比较多样,这里不说了,放一篇链接:《柚子工具 - Groovy&Java动态编译执行》。里面介绍了groovy执行的两种方式,你可以到百度上谷歌一下,还有更多其他方法。后面也提到,动态脚本的效率没法和Java比,而Java也支持动态编译。所以我们这里说一下Java的编译。
Java 动态编译
上面那篇外部引用讲了如何进行动态编译,这里就不重复讲解了。不过我想给大家介绍一个工具,能够方便的进行内存中代码的动态编译:
<dependency>
<groupId>org.jooq</groupId>
<artifactId>joor-java-8</artifactId>
<version>0.9.8</version>
</dependency>
通过以上依赖,我们可以这样编写代码:
String s = "import java.math.BigDecimal;class A{BigDecimal a(){return new BigDecimal(\"#1\").multiply(new BigDecimal(\"0.12\"));}}";
String script = s.replace("#1", "100");
log.info("结果 {}", Reflect.compile("A", script).create().call("a"));
后面的call写入方法名称即可。
Written on December 18, 2019
分类:
dev,
标签:
java
asm
如果你喜欢,请赞赏!
