Pregunta

Tengo lo siguiente:

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

¿Cómo puedo convertir el objeto de resultado que es del tipo sun.org.mozilla.javascript.internal.NativeArray a una matriz java correspondiente? ¿Puede alguien mostrarme una muestra de código de trabajo donde se hace esto? Debería funcionar para matrices de cadenas y enteros. Además, sería genial saber dónde buscar otras conversiones de tipos de datos entre el motor de rhino y Java.

Por cierto, Conozco esta página pero realmente estoy buscando un ejemplo de código de trabajo.

¿Fue útil?

Solución

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);
}

Otros consejos

No estoy seguro de si fue el caso cuando se hizo esta pregunta por primera vez, pero NativeArray implementa la interfaz java.util.List . Por lo tanto, una forma sencilla de convertir a una matriz Java real es:

Object[] array = ((List<?>) result).toArray();

Si el Javascript está bajo su control, puede hacer la transformación allí, según este documento . Entonces, para adaptar su ejemplo, algo como:

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;

Aunque, si no puede cambiar el Javascript, este enfoque no funcionará, y [i] tendrá [/ i] una instancia de sun.org.mozilla.javascript.internal.NativeArray como su resultado variable. En ese momento, creo que solo necesitas lanzarlo y tratarlo directamente, usando cualquier método público que exponga; Probablemente no sea bonito, pero no veo otras opciones. En particular, creo que lo único que puede garantizar en el buen nivel de Rhino es que será una instancia de Scriptable (y probablemente ScriptableObject ), que no lo ayudará Úselo como una matriz.

La respuesta de Kevin se ve como una buena manera de ir aquí (¡y es similar a lo que estaba a punto de editar! :-))

Solución general usando JSON como intermediario de datos:

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());
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top