表达式评估(运行)
Liquor 表达式工具,是基于 Java 编译实现的。在“缓存覆盖”下,性能接近原始 Java 代码。但是,当有“无限多变化”的表达式时,缓存会失效,且会产生无限多的类,然后 OOM。
当有“无限多变化”的表达式时(意味着,缓存被击穿;新增无限多的编译类):
- 使用“变量”替代常量,以减少编译
Exprs.eval(new CodeSpec("a+b+c"), context)
。- 【推荐】效果,就像类与实例的关系
- 使用非缓存模式
Exprs.eval(new CodeSpec("1+2+3").cached(false))
- 【不推荐】
推荐更专业的表达式工具(比如,aviator)。
表达式编写提要
- 必须有结果返回
- 表达式中没有 ";" 时,会自动添加 "return" 和 ";"。否则要自己确保语句完整
- 可使用 CodeSpec::imports 导入表达式需要的类、或静态函数
常量表达式计算演示【不推荐】
// 数学运算 (Long)
Integer result = (Integer) Exprs.eval("1+2+3");
System.out.println(result); // 6
// 数学运算 (Double)
Double result2 = (Double) Exprs.eval("1.1+2.2+3.3");
System.out.println(result2); // 6.6
// 包含关系运算和逻辑运算
System.out.println(Exprs.eval("(1>0||0<1)&&1!=0")); // true
// 三元运算
System.out.println(Exprs.eval("4 > 3 ? \"4 > 3\" : 999")); // 4 > 3
变量表达式计算演示【推荐】
不管 a,b 数值怎么变,只会有一个编译类。
Map<String, Object> context = new HashMap<>();
context.put("a", 1);
context.put("b", 2);
Exprs.eval("(a + b) * 2", context);
多语句表达式演示(类似脚本)
当有 ;
时,可以编写完整的 java 代码。此时,可以书写多语句表达式,但需要自己返回结果。
Map<String, Object> context = new HashMap<>();
context.put("a", 1);
context.put("b", 2);
Exprs.eval("int c; if (a < 0) { c=b; } else { c=0; } return c;", context);
扩展类或函数调用演示(可以使用整个 JDK 里的类,可以自定义)
支持类导入,并直接使用
CodeSpec exp5 = new CodeSpec("Math.min(1,2)").imports(Math.class);
System.out.println(Exprs.eval(exp5));
支持静态函数导入,并直接使用(开发是扩展函数时,只需要编写成静态函数即可)
CodeSpec exp6 = new CodeSpec("min(11,21)").imports("static java.lang.Math.*");
System.out.println(Exprs.eval(exp6));