基本上,我希望调用具有相同的效果:
ScriptEngineManager::put(String key, Object value)
但是对于Java类型。就像是:
ScriptEngineManager::put(String key, Class<?> clazz)
这样,例如,在调用之后:
scriptEngineManager.put("MyClass", MyClass.class)
我将能够做到:
ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn");
engine.eval("MyClass.myStaticMethod();")
可能吗?
谢谢!
最佳答案
是的,可以调用Java static
方法。也许有一种更简单的方法,但是我想出了以下方法。
假设您有2个Java类Adder
和Arithm
:
public class JSNashorn {
public static class Adder {
int total=0;
public Adder() {}
public int add(int x) { return total+=x;}
public int getTotal() { return total;}
}
public static class Arithm {
public static int sum(int a, int b) {
return a+b;
}
public static int mul(int a, int b) {
return a*b;
}
}
//...
}
初始化JS引擎:
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine jsEngine = factory.getEngineByName("nashorn");
Invocable iv = (Invocable)jsEngine;
为了在实例上调用Java方法:
jsEngine.eval("function makeJsObject(nativeObject) { return {nativeObject:nativeObject}; };");
Object adder = iv.invokeFunction("makeJsObject", new Adder());
jsEngine.put("adder", adder);
jsEngine.eval("adder.add = function(x) { return this.nativeObject.add(x); };");
System.out.println("add: "+iv.invokeMethod(adder, "add", 67));
System.out.println("add: "+iv.invokeMethod(adder, "add", 33));
此打印:
add: 67
add: 100
现在对于
static
方法: jsEngine.eval("function makeJsClass(nativeClass) { return Java.type(nativeClass); };");
Object arithm = iv.invokeFunction("makeJsClass", "JSNashorn$Arithm");
jsEngine.put("arithm", arithm);
jsEngine.eval("sum = function(x,y) { return arithm.sum(x,y); };");
jsEngine.eval("mul = function(x,y) { return arithm.mul(x,y); };");
System.out.println("sum: "+iv.invokeFunction("sum", 100, -2));
System.out.println("mul: "+iv.invokeFunction("mul", 100, -2));
此打印:
sum: 98
mul: -200