在 Nashorn 中将 javascript 名称设置为 Java 函数
Set a javascript name to be a Java function in Nashorn
我想为 Nashorn 提供一个功能,如下所示:
public class Whosebug {
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 不是对象。如何将 java 脚本名称设置为 java 函数?
编辑澄清:
在Java脚本中,我们可以这样写:
var square = function(y) {
return y * y;
};
square(9);
如果我在 Java 中写了 square
,我怎样才能将该函数分配给 Java脚本变量?
感谢@Seelenvirtuose,事实证明您只需将它设置为 Consumer
(或任何其他功能接口),然后 Nashorn 就会做正确的事情。下面的测试通过了。
public class Whosebug {
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 表达式传递给脚本:JScriptBox。对我有帮助,也许对你也有帮助。
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);
}
我想为 Nashorn 提供一个功能,如下所示:
public class Whosebug {
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 不是对象。如何将 java 脚本名称设置为 java 函数?
编辑澄清:
在Java脚本中,我们可以这样写:
var square = function(y) {
return y * y;
};
square(9);
如果我在 Java 中写了 square
,我怎样才能将该函数分配给 Java脚本变量?
感谢@Seelenvirtuose,事实证明您只需将它设置为 Consumer
(或任何其他功能接口),然后 Nashorn 就会做正确的事情。下面的测试通过了。
public class Whosebug {
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 表达式传递给脚本:JScriptBox。对我有帮助,也许对你也有帮助。
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);
}