Java Nashorn引擎ArrayNode处理

Java Nashorn引擎ArrayNode处理,java,nashorn,Java,Nashorn,我使用JavaNashorn引擎来执行Javascript代码。我使用ScriptEngine对象的eval方法,该方法有第二个“bindings”参数。我使用它将变量传递给引擎。它适用于对象类型和原始包装器类,但当我尝试传递ArrayNode时,它不能作为JavaScript数组使用,我不知道为什么 示例代码: String scriptText = "myarray[1] = 666"; ScriptEngine engine = new ScriptEngineManager().getE

我使用JavaNashorn引擎来执行Javascript代码。我使用
ScriptEngine对象的
eval
方法,该方法有第二个“bindings”参数。我使用它将变量传递给引擎。它适用于对象类型和原始包装器类,但当我尝试传递ArrayNode时,它不能作为JavaScript数组使用,我不知道为什么

示例代码:

String scriptText = "myarray[1] = 666";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Bindings bindings = engine.createBindings();
ArrayNode arrayNode = mapper.createArrayNode();
array.add(1);
array.add(2);
array.add(3);

bindings.put("myarray", arrayNode);
engine.eval(scriptText, bindings);
这应该会更改bindings对象中的myarray值,但不会更改


我做错了什么?

Nashorn支持脚本数组,比如对

  • Java数组对象
  • java.util.ArrayList对象
  • jdk.nashorn.api.scripting.JSObject对象
  • 如果ArrayNode不是ArrayList子类型,则可以在ArrayNode类中实现JSObject接口,或者使用JSObject实现包装ArrayNode并将其公开给脚本()

    举例说明上述三种情况:

    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])");
     }
    }
    
    import java.util.*;
    导入javax.script.*;
    导入jdk.nashorn.api.scripting.*;
    公共班机{
    公共静态void main(字符串[]args)引发异常{
    ScriptEngineManager m=新ScriptEngineManager();
    ScriptEngine e=m.getEngineByName(“nashorn”);
    //通过索引访问Java数组
    字符串[]arr={“你好”,“世界”};
    e、 put(“jarr”,arr);
    e、 eval(“jarr[1]=jarr[1].toUpperCase()”;//更改第一个元素
    System.out.println(arr[1]);//此处反映的更改
    //通过索引访问Java ArrayList
    ArrayList alist=新的ArrayList();
    添加(“纳肖恩”);
    添加(“javascript”);
    e、 put(“jlist”,alist);
    e、 eval(“jlist[0]='Nashorn'”;
    System.out.println(alist.get(1));//此处反映的更改
    //第三种情况-通过索引访问的类似JSObject数组的对象
    e、 put(“myObj”,新的AbstractJSObject(){
    私有映射值=新的HashMap();
    @凌驾
    公共无效设置批次(整数索引,对象值){
    值。put(索引,val);
    }
    @凌驾
    公共对象getSlot(int索引){
    返回值.get(索引);
    }
    });
    e、 eval(“myObj[0]=“你好”);
    e、 评估(“打印(myObj[0])”;
    }
    }
    
    Nashorn支持脚本数组,如对

  • Java数组对象
  • java.util.ArrayList对象
  • jdk.nashorn.api.scripting.JSObject对象
  • 如果ArrayNode不是ArrayList子类型,则可以在ArrayNode类中实现JSObject接口,或者使用JSObject实现包装ArrayNode并将其公开给脚本()

    举例说明上述三种情况:

    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])");
     }
    }
    
    import java.util.*;
    导入javax.script.*;
    导入jdk.nashorn.api.scripting.*;
    公共班机{
    公共静态void main(字符串[]args)引发异常{
    ScriptEngineManager m=新ScriptEngineManager();
    ScriptEngine e=m.getEngineByName(“nashorn”);
    //通过索引访问Java数组
    字符串[]arr={“你好”,“世界”};
    e、 put(“jarr”,arr);
    e、 eval(“jarr[1]=jarr[1].toUpperCase()”;//更改第一个元素
    System.out.println(arr[1]);//此处反映的更改
    //通过索引访问Java ArrayList
    ArrayList alist=新的ArrayList();
    添加(“纳肖恩”);
    添加(“javascript”);
    e、 put(“jlist”,alist);
    e、 eval(“jlist[0]='Nashorn'”;
    System.out.println(alist.get(1));//此处反映的更改
    //第三种情况-通过索引访问的类似JSObject数组的对象
    e、 put(“myObj”,新的AbstractJSObject(){
    私有映射值=新的HashMap();
    @凌驾
    公共无效设置批次(整数索引,对象值){
    值。put(索引,val);
    }
    @凌驾
    公共对象getSlot(int索引){
    返回值.get(索引);
    }
    });
    e、 eval(“myObj[0]=“你好”);
    e、 评估(“打印(myObj[0])”;
    }
    }
    
    Wow!这是一个惊人的答案!谢谢:)工作起来很有魅力:)哇!这是一个惊人的答案!谢谢:)效果很好:)