Java Nashorn 引擎 ArrayNode 处理
Java Nashorn engine ArrayNode handling
我使用 Java Nashorn 引擎 来执行 Java 脚本代码。我使用 ScriptEngine object
的 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);
这应该会更改绑定对象中的 myarray 值,但实际上并没有。
我做错了什么?
Nashorn 在
上支持脚本数组索引 access/update
- Java 数组对象
- java.util.ArrayList 个对象
- jdk.nashorn.api.scripting.JSObject 个对象
如果 ArrayNode 不是 ArrayList 子类型,您可以在 ArrayNode class 中实现 JSObject 接口,或者用 JSObject 实现包装 ArrayNode 并将其暴露给脚本 (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])");
}
}
我使用 Java Nashorn 引擎 来执行 Java 脚本代码。我使用 ScriptEngine object
的 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);
这应该会更改绑定对象中的 myarray 值,但实际上并没有。
我做错了什么?
Nashorn 在
上支持脚本数组索引 access/update- Java 数组对象
- java.util.ArrayList 个对象
- jdk.nashorn.api.scripting.JSObject 个对象
如果 ArrayNode 不是 ArrayList 子类型,您可以在 ArrayNode class 中实现 JSObject 接口,或者用 JSObject 实现包装 ArrayNode 并将其暴露给脚本 (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])");
}
}