我有一个静态方法,如:
some abstract class C {
void dump( Object o ) {
}
我希望传递给js,我可以直接在全球范围内使用它,如:
js> dump( new Something() );
到目前为止,我找到的唯一方法是创建一个像
这样的实例public class CStub {
void dump( Object o ){ C.dump( o ); }
}
通过以下方式将它放入nashorn:
engine.put( "stub", new CStub() );
然后在js:
js> var dump = stub.dump
但是还有另一种方法,它不涉及存根创建并将方法直接放在全局范围内吗?
答案 0 :(得分:7)
您可以在类中实现类似java.util.function.Function的函数接口(https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html),并将其对象作为全局变量公开给nashorn。 Nashorn对待任何"功能界面"对象作为一个函数,允许直接调用它。 公开" dump"的简单示例功能如下:
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')");
}
}
答案 1 :(得分:3)
更短,您可以采用方法引用(C::dump
),将其转换为适当的功能接口(在您的情况下Consumer
很好,因为它接收单个参数并返回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')");
}
}