基本上,我希望调用具有相同的效果:

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类AdderArithm

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

10-02 05:05