18

我有以下内容:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
Object result = jsEngine.eval("getArray();");

如何将 sun.org.mozilla.javascript.internal.NativeArray 类型的结果对象转换为相应的 java 数组?有人可以向我展示一个工作代码示例吗?它应该适用于字符串和整数数组。另外,很高兴知道在哪里可以找到 rhino 引擎和 java 之间的其他数据类型转换。

顺便说一句,我知道这个页面,但我真的在寻找一个工作代码示例。

4

5 回答 5

24
NativeArray arr = (NativeArray) result;
Object [] array = new Object[(int) arr.getLength()];
for (Object o : arr.getIds()) {
    int index = (Integer) o;
    array[index] = arr.get(index, null);
}
于 2009-09-16T14:49:43.007 回答
9

我不确定第一次提出这个问题时是否是这种情况,但NativeArray实现了java.util.List接口。因此,转换为真正的 Java 数组的一种简单方法是:

Object[] array = ((List<?>) result).toArray();
于 2013-12-05T16:09:25.643 回答
8

如果 Javascript 在您的控制之下,您可以按照此文档在那里进行转换。因此,为了调整您的示例,例如:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
String convertFuncSrc =
     "function convertArray(type, arr) {"
   + "  var jArr = java.lang.reflect.Array.newInstance(type, arr.length);"
   + "  for (var i = 0; i < arr.length; i++) { "
   + "    jArr[i] = arr[i];"
   + "  }"
   + "  return jArr;"
   + "};";
jsEngine.eval(convertFuncSrc);
Object result = jsEngine.eval("convertArray(java.lang.Integer.TYPE, getArray());");
int[] javaArray = (int[])result;

虽然,如果您不能更改 Javascript,这种方法将不起作用,并且您 [i] 将 [/i] 将 sun.org.mozilla.javascript.internal.NativeArray 的实例作为您的result变量。在这一点上,我认为您只需要使用它公开的任何公共方法直接转换和处理它;它可能不漂亮,但我没有看到任何其他选择。特别是,我认为您可以在好的 Rhino 级别上保证的唯一一件事是它将是Scriptable(并且可能ScriptableObject)的一个实例,这无助于您将它用作数组。

凯文的回答看起来像是一个很好的方式(并且类似于我刚刚要编辑的内容!:-))

于 2009-09-16T14:47:57.987 回答
0

使用 JASON 作为数据中间体的通用解决方案:

Object result = jsEngine.eval("JSON.stringify(getArray())");    
JsonReader jsonReader = Json.createReader(new StringReader(result.toString()));
JsonArray jsonArray = jsonReader.readArray();
jsonReader.close();
int[] numbers = new int[jsonArray.size()];
int index = 0;
for(JsonValue value : jsonArray){
    numbers[index++] = Integer.parseInt(value.toString());
}
于 2017-08-28T15:42:59.417 回答
0

就我而言,我想在脚本中生成一个 Java 数组。(这个用例也符合这个问题。)

创建 Java 数组之后,我想出了

var javaArray = java.lang.reflect.Array.newInstance(java.lang.Integer, jsArray.length);
for (var i = 0; i < javaArray.length; i++) {
  javaArray[i] = new java.lang.Integer(jsArray[i]);
}
于 2020-10-08T19:15:22.777 回答