【问题标题】:How to convert Rhino-JavaScript arrays to Java-Arrays如何将 Rhino-JavaScript 数组转换为 Java-Arrays
【发布时间】:2010-11-28 20:04:16
【问题描述】:

我有以下几点:

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 之间的其他数据类型转换。

顺便说一句,i know this page 但我真的在寻找一个工作代码示例。

【问题讨论】:

    标签: java scripting rhino jsr223


    【解决方案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);
    }
    

    【讨论】:

    • 感谢您帮助一个愚蠢的家伙 ;-) 我希望所有的答案都是那么准确、简短和有效!
    • 想知道为什么您不能将整个 getIds 数组转换为 Integer[]。我得到一个 ClassCastException。哦,好吧
    【解决方案2】:

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

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

    【讨论】:

    • jdk1.6.0_45 说 sun.org.mozilla.javascript.internal.NativeArray 不能转换为 java.util.List
    • @pal NativeArray 在更新的 Rhino 版本中确实实现了 List,但我不确定这是什么时候出现的。见here
    • 顺便说一下,Nashorn(Java 8 中包含的 JavaScript 引擎)不幸地返回了实现 Map 而不是 List 的类 (ScriptObjectMirror) 的对象。如果您希望您的代码同时在 Java 7 和 8+ 下工作,则必须进行 instanceof 检查。
    【解决方案3】:

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

    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)的一个实例,这无助于你将它用作一个数组。

    Kevin's answer 看起来是个不错的选择(与我刚要编辑的内容相似!:-))

    【讨论】:

      【解决方案4】:

      使用 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());
      }
      

      【讨论】:

        【解决方案5】:

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

        跟着@​​987654321@,我想出了

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-02-26
          • 1970-01-01
          • 1970-01-01
          • 2013-05-27
          • 2014-04-30
          • 1970-01-01
          • 2011-11-27
          相关资源
          最近更新 更多