在java

时间:2016-10-20 21:51:53

标签: java scriptengine javax.script

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

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

logic是接触我想要评估的逻辑的字符串,curname是当前节点名称被替换为它的布尔值(" in1"例如)它在循环中所以所有节点名称在字符串之前被替换评估,nodes是节点的数组列表,ins是节点数组中输入节点的索引,getState()返回节点布尔值,这个工作正常,将逻辑字符串的新值设置为&#34 ;真实&&真"

困难的部分是将字符串作为布尔值进行评估。我发现我可以使用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)));

它只返回false。

oracle's page on eval上,我看到有一些其他参数可以传递给eval,我是否缺少其中一个或者完全是其他的东西?

*旁注,这不是我在这里没有显示的任何代码中的问题,我已经用粗线条而不是字符串测试了评估。

1 个答案:

答案 0 :(得分:3)

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

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