如何在Oracle Nashorn中覆盖和调用Java对象上的函数?

时间:2014-10-23 18:12:16

标签: java javascript nashorn

我有一个Java对象,需要通过一些Java代码进行初始化。然后将该对象放入nashorn引擎中。将调用一些JavaScript代码,它们将覆盖此对象上的方法。后来在Java中应该调用覆盖的方法。

此代码不起作用:

首先:方法“测试”未被覆盖 - >调用它返回“3”。 第二:调用原始的“test”方法失败,异常“无法在非脚本对象上调用getInterface”

public static class O
{
  public int mV = 0;
  public O(int V)
  {
    mV = V;
  }

  public Object test (Object o)
  {
    return mV;
  }
}

public static void main(String[] args)
{
  ScriptEngineManager factory = new ScriptEngineManager();
  ScriptEngine jsEngine = factory.getEngineByName("nashorn");
  Invocable iv = (Invocable)jsEngine;
  try
  {
    Object o = new O(3);
    jsEngine.put("o", o);

    jsEngine.eval("o.test = function(x) { return mV * x; };");

    Object test = jsEngine.eval("o.test(8);");           // test is 3 here

    o = jsEngine.get("o");
    Object result = iv.invokeMethod(o, "test", 4);       // this line will throw an exception
    System.out.println(result.toString());
  }
  catch (Exception e1)
  {
    e1.printStackTrace();
  }

1 个答案:

答案 0 :(得分:0)

好的,明白了。我无法向Java对象添加函数。我通过辅助函数“makeJsObject”创建一个JS对象,并在属性中保留对Java对象的引用。然后我可以向JS对象添加一个方法,并通过Java中的invokeMethod调用它。

    jsEngine.eval("function makeJsObject(nativeObject) { return {nativeObject:nativeObject}; };");

    O o = new O(3);
    Object q = iv.invokeFunction("makeJsObject", o);
    jsEngine.put("q", q);


    jsEngine.eval("q.test = function(x) { return this.nativeObject.test(this.nativeObject.mV * x); };");


    Object result = iv.invokeMethod(q, "test", 4);
相关问题