2015-03-04 1 views
1

В основном я хотел бы иметь тот же эффект вызова:Как добавить Java-тип в глобальную область nashorn engine из java?

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();") 

Возможно ли это?

Спасибо!

ответ

0

Да, можно вызвать методы 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 
+0

Спасибо за все усилия, которые вы положили в этот ответ! В любом случае, чтобы вызвать метод экземпляра, вам просто нужно вызвать 'jsEngine.put (« сумматор », сумматор);' не нужно переопределять его методы как функции javascript, вы можете просто называть его 'jsEngine .eval ("adder.add (33);") '. Для статических методов я придумал решение, подобное вашему, но я хотел знать, был ли «чистый» способ сделать это ... – jamp

 Смежные вопросы

  • Нет связанных вопросов^_^