Nashorn通过JS中的函数引用调用java对象的方法(通过绑定传递)

时间:2018-04-17 16:23:01

标签: javascript java nashorn

我想将原生Java对象放入ScriptEngine绑定中以便于访问。

scriptEngine.put("myApi", myApiInstance);

这里“myApiInstance”有一个非静态方法“foo()”。

现在在JS中我有一个功能:

someJsFunction(func) { func.call(...) }

但是电话

someJsFunction(myApiInstance.foo)

结果为“TypeError:func.call不是函数”。

另一方面,“myApiInstance.foo()”按预期工作。 这看起来像ScripEngine细节,因为“call()”方法应该在任何函数中都可用。 是的,“typeof myApiInstance.foo”返回“function”

1 个答案:

答案 0 :(得分:3)

Java方法和函数接口对象(lambda对象)被视为脚本函数,因此可以像往常一样从JavaScript调用。如你所说" typeof"在这些对象上返回true。您可以直接从脚本中调用它们。但是这些并不是真正的JS函数对象,因为它们的原型不是Function.prototype。也就是说,如果你想使用Function.prototype.call或.apply来调用它们,[说你要调度到任何可传递的callable),你可以执行以下操作:

import javax.script.*;

public class Main {
  public static void main(String[] args) throws Exception {
    ScriptEngineManager m = new ScriptEngineManager();
    ScriptEngine e = m.getEngineByName("nashorn");

    // get the java static method to call
    e.eval("var getProp = java.lang.System.getProperty");
    // direct call
    e.eval("print(getProp('java.home'))");

    // call using Function.prototype.call
    e.eval("print(Function.prototype.call.call(getProp, null, 'java.home'))");

    // a java object
    e.eval("var out = java.lang.System.out");
    // get an instance method
    e.eval("var p = out.println");
    // call java instance method using Function.prototype.call
    e.eval("Function.prototype.call.call(p, out, 'hello world')");
  }
}