Java/Nashorn将一个函数放入绑定/全局范围

Java/Nashorn将一个函数放入绑定/全局范围,java,scope,nashorn,Java,Scope,Nashorn,我有一个静态方法,如: some abstract class C { void dump( Object o ) { } 我想将其传递给js,以便在全局范围内直接使用它,如: js> dump( new Something() ); 到目前为止,我找到的唯一方法是创建一个 public class CStub { void dump( Object o ){ C.dump( o ); } } 通过以下方式将其放入纳肖恩: engine.put( "stub", ne

我有一个静态方法,如:

some abstract class C {
    void dump( Object o ) {
}
我想将其传递给js,以便在全局范围内直接使用它,如:

js> dump( new Something() );
到目前为止,我找到的唯一方法是创建一个

public class CStub {
    void dump( Object o ){ C.dump( o ); }
}
通过以下方式将其放入纳肖恩:

engine.put( "stub", new CStub() );
然后在js中:

js> var dump = stub.dump

但是有没有另一种方法不涉及存根创建并将方法直接放入全局范围?

您可以在类中实现一个函数接口(),如java.util.function.function,并将其对象作为全局变量公开给nashorn。Nashorn将任何“functional interface”对象视为函数,并允许直接调用它。 公开“转储”函数的简单示例如下:

import javax.script.*;
import java.util.function.Function;

public class Main {
   // a Function implementation
   private static class MyFunc implements Function<String, Void> {
       @Override
       public Void apply(String msg) {
           System.out.println(msg);
           return null;
       }
   }

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

       // expose functional interface object as a global var
       e.put("dump", new MyFunc());

       // invoke functional interface object like a function!
       e.eval("dump('hello')");
   }
}
import javax.script.*;
导入java.util.function.function;
公共班机{
//函数实现
私有静态类MyFunc实现函数{
@凌驾
公共无效应用(字符串消息){
System.out.println(msg);
返回null;
}
}
公共静态void main(字符串[]args)引发异常{
ScriptEngineManager m=新ScriptEngineManager();
ScriptEngine e=m.getEngineByName(“nashorn”);
//将函数接口对象公开为全局变量
e、 put(“dump”,new MyFunc());
//像调用函数一样调用函数接口对象!
e、 eval(“转储('hello')”);
}
}

更简短地说,您可以获取方法引用(
C::dump
),将其转换到适当的函数接口(在您的情况下,
使用者
可以,因为它接收单个参数并返回void),然后将其放入全局范围

import javax.script.*;
import java.util.function.Consumer;

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

        // expose method-reference-as-function-object as a global var
        e.put("dump", (Consumer<Object>)C::dump);

        // invoke functional interface object like a function!
        e.eval("dump('hello')");
    }
}
import javax.script.*;
导入java.util.function.Consumer;
公共班机{
公共静态void main(字符串[]args)引发异常{
ScriptEngineManager m=新ScriptEngineManager();
ScriptEngine e=m.getEngineByName(“nashorn”);
//将方法引用作为函数对象公开为全局变量
e、 put(“转储”,(消费者)C::转储);
//像调用函数一样调用函数接口对象!
e、 eval(“转储('hello')”);
}
}

嘿,非常感谢!它起作用了。不过有点奇怪,这正是我最后所做的。出乎意料的是,java端的方法签名与使用实例时略有不同。