问题
I am trying to evaluate "in1 && in2"
to a Boolean as a test, but i hope to be able to evaluate all booleans as stings for my actual project. in1 and in2 are the names of nodes that have a boolean state, i get the actual expression like so,
logic = logic.replaceAll(curName, (nodes.get(ins.get(j)).getState() ? "true" : "false"));
logic is the string contacting the logic i want evaluated, curname is the current node name being replaced with its boolean("in1" for example) its in a loop so all node names are replaced before the string is evaluated, nodes is an array list of nodes, ins are the indexes of the input nodes in the node array, getState()
returns the nodes boolean value this works fine, setting the new value of the logic string to "true && true".
The hard part is evaluating the string as a Boolean. I found that i could use javax.script to help me here. So I implemented it as so
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
nodes.get(outs.get(i)).setState((boolean)se.eval(logic));
The problem is that it evaluates to false every time, When i try and cast the object returned by eval as a Boolean and try to display it like so,
System.out.printLine(String.valueOf((boolean)se.eval(logic)));
it only returns false.
On oracle's page on eval, I see that there are some other parameters that can be passed to eval, am i missing one of them or is it something else entirely?
*Side note, it is not a problem in any of the code i haven't shown here, ive already tested the evaluation with raw booleans rather then a string.
回答1:
No need to modify the script. Just send in the values as variables.
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);
}
Output
false
false
false
true
You can even pre-compile the script for better performance.
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);
}
}
来源:https://stackoverflow.com/questions/40165157/evaluating-a-string-holding-a-logic-operation-as-a-boolean-in-java