在 java 中评估包含逻辑运算的字符串作为布尔值

Evaluating a string holding a logic operation as a Boolean in java

我正在尝试将 "in1 && in2" 评估为布尔值作为测试,但我希望能够将所有布尔值评估为我的实际项目的 stings。 in1 和 in2 是具有布尔状态的节点的名称,我得到这样的实际表达式,

logic = logic.replaceAll(curName, (nodes.get(ins.get(j)).getState() ? "true" : "false"));

logic 是联系我想要评估的逻辑的字符串,curname 是当前节点名称被替换为它的布尔值(例如“in1”)它在一个循环中所以所有节点名称在评估字符串之前被替换, nodes 是节点数组列表,ins 是节点数组中输入节点的索引,getState() returns 节点布尔值这很好用,将逻辑字符串的新值设置为“true” && 真。

困难的部分是将字符串作为布尔值求值。我发现我可以使用 javax.script 来帮助我 here。所以我就这样实现了

ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
nodes.get(outs.get(i)).setState((boolean)se.eval(logic)); 

问题是它每次都计算为 false,当我尝试将 eval 返回的对象转换为布尔值并尝试像这样显示它时,

System.out.printLine(String.valueOf((boolean)se.eval(logic)));

它只是 returns 错误。

oracle's page on eval 上,我发现还有一些其他参数可以传递给 eval,我是缺少其中一个还是完全是其他参数?

*旁注,我在这里没有显示的任何代码都不是问题,我已经用原始布尔值而不是字符串测试了评估。

无需修改脚本。只需将值作为变量发送。

public static void main(String[] args) throws Exception {
    test(false, false);
    test(false, true );
    test(true , false);
    test(true , true );
}
private static void test(boolean in1, boolean in2) throws ScriptException {
    ScriptEngineManager engineManager = new ScriptEngineManager();
    ScriptEngine engine = engineManager.getEngineByName("JavaScript");
    Bindings vars = engine.getBindings(ScriptContext.ENGINE_SCOPE);
    vars.put("in1", in1);
    vars.put("in2", in2);
    boolean result = (boolean) engine.eval("in1 && in2");
    System.out.println(result);
}

输出

false
false
false
true

您甚至可以预编译脚本以获得更好的性能。

public class Test {
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        System.out.println(test.test(false, false));
        System.out.println(test.test(false, true ));
        System.out.println(test.test(true , false));
        System.out.println(test.test(true , true ));
    }

    private ScriptEngine   jsEngine;
    private CompiledScript script;

    private Test() throws ScriptException {
        this.jsEngine = new ScriptEngineManager().getEngineByName("JavaScript");
        this.script = ((Compilable) this.jsEngine).compile("in1 && in2");
    }

    private boolean test(boolean in1, boolean in2) throws ScriptException {
        Bindings vars = this.jsEngine.createBindings();
        vars.put("in1", in1);
        vars.put("in2", in2);
        return (boolean) this.script.eval(vars);
    }
}