2

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

此代码不起作用:

首先:方法“test”没有被覆盖->调用它返回“3”。第二:调用原始“test”方法失败,出现异常“getInterface cannot be called on non-script object”

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();
  }
4

1 回答 1

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);
于 2014-10-23T18:41:27.420 回答