2009-09-16 15 views
17

Ho il seguente:come convertire gli array Rhino-JavaScript per Java-Array

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

come posso convertire l'oggetto risultato che è di tipo sun.org.mozilla.javascript.internal.NativeArray ad un array java corrispondente? Qualcuno può mostrarmi un codice di lavoro campione dove questo è fatto? Dovrebbe funzionare per gli array String e Integer. Inoltre, sarebbe bello sapere dove cercare altre conversioni di tipi di dati tra il motore di rhino e java.

Btw, i know this page ma sto davvero cercando un esempio di codice funzionante.

risposta

22
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); 
} 
+0

grazie per aiutare un ragazzo stupido ;-) Vorrei che tutte le risposte che sarebbero preciso, corto e funzionante! – Chris

+0

Ti chiedi perché non puoi lanciare l'intero array getIds su Integer []. Sto ricevendo un ClassCastException. Oh bene – TheLQ

7

Se Javascript è sotto il vostro controllo, è possibile effettuare la trasformazione lì, come da this document. Quindi, per adattare il vostro esempio, qualcosa come:

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; 

Anche se, se non è possibile modificare il codice Javascript questo approccio non funziona, e si [i] si [/ i] avere un'istanza di sun.org .mozilla.javascript.internal.NativeArray come variabile result. A quel punto penso che devi solo scriverlo e affrontarlo direttamente, usando qualunque metodo pubblico esponga; probabilmente non è bello ma non vedo altre opzioni. In particolare, penso che l'unica cosa che si può garantire al livello di Rhino è che sarà un'istanza di Scriptable (e probabilmente ScriptableObject), che non aiuta a usarlo come array.

Kevin's answer sembra un buon modo per andare qui (ed è simile a quello che ero sul punto di modificare in! :-))

8

io non sono sicuro se fosse il caso in cui tale la prima domanda è stata posta, ma NativeArray implementa l'interfaccia java.util.List. Un modo semplice per convertire in una vera e propria gamma di Java è quindi:

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

jdk1.6.0_45 dice che sun.org.mozilla.javascript.internal.NativeArray non può essere lanciato su java.util.List – pal

+0

@pal NativeArray implementa definitivamente l'elenco nelle versioni più recenti di Rhino, ma non sono sicuro quando questo è stato il primo caso. Vedi [qui] (http://javadox.com/org.mozilla/rhino/1.7R3/org/mozilla/javascript/NativeArray.html). –

+1

A proposito, Nashorn (il motore JavaScript incluso con Java 8) restituisce purtroppo oggetti di una classe (ScriptObjectMirror) che implementa Map invece di List. Se vuoi che il tuo codice funzioni con Java 7 e 8+, dovrai eseguire un'istanza di controllo. –

0

soluzione generale utilizzando JASON come dati intermedi:

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()); 
} 
Problemi correlati