Ответ 1
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);
}
У меня есть следующее:
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? Может ли кто-нибудь показать мне пример рабочего кода , где это делается? Он должен работать для массивов String и Integer. Кроме того, было бы здорово знать, где искать другие преобразования типа данных между движком rhino и java.
Btw, Я знаю эту страницу, но я действительно ищу пример рабочего кода.
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);
}
Я не уверен, был ли этот случай впервые задан, но NativeArray
реализует интерфейс java.util.List
. Таким образом, простой способ преобразования в настоящий массив Java:
Object[] array = ((List<?>) result).toArray();
Если 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
), что не поможет вам использовать его в качестве массива.
Ответ Кевина выглядит как хороший способ пойти сюда (и похож на то, что я только что редактировал в::))
Общее решение с использованием 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());
}