Java Nashorn引擎ArrayNode处理

时间:2018-04-18 12:14:11

标签: java nashorn

我使用 Java Nashorn引擎来执行Javascript代码。我使用eval的{​​{1}}方法,它有第二个参数用于"绑定"。我用它来将变量传递给引擎。它适用于Object类型和原始包装类,但是当我尝试传递ArrayNode时,它不能用作JavaScript数组,我不知道为什么。

示例代码:

ScriptEngine object

这应该更改绑定对象中的myarray值,但它不会。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

Nashorn支持

上类似脚本数组的索引访问/更新
  1. Java数组对象
  2. java.util.ArrayList objects
  3. jdk.nashorn.api.scripting.JSObject objects
  4. 如果ArrayNode不是ArrayList子类型,您可以在ArrayNode类中实现JSObject接口,或者使用JSObject实现&amp ;;将其暴露给脚本(https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/JSObject.html)。

    一个证明上述三种情况的例子:

    import java.util.*;
    import javax.script.*;
    import jdk.nashorn.api.scripting.*;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");
    
        // Java array accessed by indexing
        String[] arr = { "hello", "world" };
        e.put("jarr", arr);
        e.eval("jarr[1] = jarr[1].toUpperCase()"); // change first element
        System.out.println(arr[1]); // change reflected here
    
        // Java ArrayList accessed by indexing
        ArrayList<String> alist = new ArrayList<>();
        alist.add("nashorn");
        alist.add("javascript");
        e.put("jlist", alist);
        e.eval("jlist[0] = 'Nashorn'");
        System.out.println(alist.get(1)); // change reflected here
    
        // Third case - a JSObject array-like object accessed by indexing
        e.put("myObj", new AbstractJSObject() {
            private Map<Integer, Object> values = new HashMap<>();
            @Override
            public void setSlot(int index, Object val) {
                values.put(index, val);
            }
    
            @Override
            public Object getSlot(int index) {
                return values.get(index);
            }
       });
    
       e.eval("myObj[0] = 'hello'");
       e.eval("print(myObj[0])");
     }
    }