在Nashorn中将javascript名称设置为Java函数
我想为Nashorn提供一个函数,如下所示:在Nashorn中将javascript名称设置为Java函数,javascript,java,java-8,nashorn,Javascript,Java,Java 8,Nashorn,我想为Nashorn提供一个函数,如下所示: public class StackOverflow { private Object toSave; @Test public void test() { ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn"); ScriptContext context = jsEngine.getConte
public class StackOverflow {
private Object toSave;
@Test
public void test() {
ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");
ScriptContext context = jsEngine.getContext();
context.setAttribute("saveValue", arg -> { toSave = arg; }, ScriptContext.ENGINE_SCOPE);
jsEngine.eval("saveValue('one')");
Assert.assertEquals("one", toSave);
}
}
上面的代码无法编译,因为ScriptContext.setAttribute()
需要一个对象,而lambda不是对象。如何将javascript名称设置为java函数
编辑以澄清:
在JavaScript中,我们可以编写以下代码:
var square = function(y) {
return y * y;
};
square(9);
如果我用Java编写了
square
,如何将该函数分配给JavaScript变量?多亏了@Seelenvirtuose,您可以将其设置为消费者
(或任何其他函数接口),然后Nashorn会做正确的事情。下面的测试通过了
public class StackOverflow {
private Object toSave;
@Test
public void test() throws ScriptException {
Consumer<String> saveValue = obj -> toSave = obj;
ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");
ScriptContext context = jsEngine.getContext();
context.setAttribute("saveValue", saveValue, ScriptContext.ENGINE_SCOPE);
jsEngine.eval("saveValue('one')");
Assert.assertEquals("one", toSave);
}
}
由于lambda表达式
arg->{toSave=arg;}
显然是一个变量,我建议将其放入该类型的变量中,并在调用setAttribute
时使用该变量(而不是lambda本身)。您试图解决的问题到底是什么?不能将lambda表达式设置为JavaScript引擎的属性。
private int square(int x) {
return x * x;
}
@Test
public void example() throws ScriptException {
TypedScriptEngine engine = JScriptBox.create()
.set("square").toFunc1(this::square)
.set("x").toValue(9)
.buildTyped(Nashorn.language());
int squareOfX = engine.eval("square(x)", Integer.class);
Assert.assertEquals(81, squareOfX);
}