当前位置: 首页 > 知识库问答 >
问题:

在Nashorn中将javascript名称设置为Java函数

松俊美
2023-03-14

我想为Nashorn提供一个函数,比如:

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.set属性()需要一个对象,而lambdas不是对象。我如何将javascript名称设置为java函数?

编辑澄清:

在JavaScript中,我们可以这样写:

var square = function(y) {
   return y * y;
};
square(9);

如果我用Java编写了square,我如何将该函数分配给JavaScript变量?

共有1个答案

符畅
2023-03-14

感谢@SeelenVirose,事实证明,您只需将其设置为消费者(或任何其他功能接口),然后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传递给script:jscript-box。帮了我,也许会帮到你。

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);
}
 类似资料:
  • 问题内容: 我希望通过以下方式在Java中实现某些功能: …根据变量名设置变量,而无需硬编码变量名并且不使用任何其他数据结构。这可能吗? 问题答案: 这是使用反射实现的方式(我已将函数重命名;针对不同的字段类型有不同的反射函数):

  • 问题内容: 有没有一种简单的方法可以将“回调”功能设置为在javascript中打开的新窗口?我想在新窗口中运行父函数,但我希望父函数能够设置此特定函数的名称(因此不应在新的Windows页面中对其进行硬编码)。 例如在父母中,我有: 在子窗口中,我要: 问题是如何创建它和功能。我虽然想将函数的名称作为查询参数发送到新窗口(服务器端脚本在生成的子HTML中生成适当的函数调用),但是我在考虑是否还有

  • 问题内容: 我经常在使用MySQL的PHP​​脚本中看到类似的内容 我从来没有对任何项目都这样做,所以我对此有两个基本问题。 这仅是通过PDO完成吗? 如果不是PDO特定的事情,那么这样做的目的是什么?我意识到它正在为mysql设置编码,但是我的意思是,我从未使用过它,所以为什么要使用它? 问题答案: 每当您要将数据发送到具有纯ASCII无法表示的字符(例如“ñ”或“ö”)的服务器时,都需要使用它

  • 使用Java 8,Nashorn,引入了一个大大改进的javascript引擎,以取代现有的Rhino。 Nashorn提供2到10倍的性能,因为它直接编译内存中的代码并将字节码传递给JVM。 Nashorn使用Java 7中引入的调用动态特性来提高性能。 jjs 对于Nashorn引擎,JAVA 8引入了一个新的命令行工具jjs,用于在控制台执行javascript代码。 解释js文件 在c:\

  • 我在Java学习线程,有一个这样的小程序。我创建一个线程,并用它来创建另一个线程。但是我不能改变第二个线程的名称。有人能解释为什么会这样吗?此外,Thread.sleep(100)意味着主线程将Hibernate100毫秒是正确的吗?谢谢。 该计划的结果如下: 编辑:如果我将getName()更改为Thread。currentThread()。getName()然后一切都按预期工作。它们之间有什么

  • 我有一个类实例,上面有一个字段。我在对象上设置了这个实例。我需要在Nashorn中设置字段,以便在Java中调用。我该如何在Nashorn脚本中设置此字段? 脚本是这样调用的: 在脚本中,我需要在全局对象上设置字段: 我已经看到了(建议重复)如何使用Nashorn引擎调用Java对象的问题,但这个问题是关于从Nashorn脚本调用Java方法,而这个问题是关于在Nashorn脚本中设置一个可调用的