Solon v3.0.3

表达式评估(运行)

</> markdown

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));