与Nashorn一起迭代阵列



使用Java的内置JavaScript解释器时,为什么我可以使用arrays.foreach((在Java列表上迭代而不是通过本机数组?我有以下测试代码

var ArrayList = Java.type('java.util.ArrayList');
var list = new ArrayList();
list.add('a');
list.add('b');
list.add('c');
var StringArray = Java.type("java.lang.String[]");
var array = new StringArray(3);
array[0] = "A";
array[1] = "B";
array[2] = "C";
list.forEach(function(v) { print(v); });
array.forEach(function(v) { print(v); });

我希望打印出来

a b c a b c

但是我得到

a b c

typeError:[ljava.lang.string;@644e4fbf没有这样的功能" for for",in Line Number 14

以下作品,但是为什么不array.foreach((?

for (var i=0; i<array.length; ++i)
  print(array[i]);

我遇到的问题是,我的JavaScript代码要调用返回字符串[]的Java功能的负载,我想处理结果对象,就好像是常规的JavaScript数组一样。是否有一种比在Java中编写大量包装器功能更容易解决此问题的方法,该功能将我的数组转换为阵列列表?

当您在Java列表上调用foreach时,您正在调用列表的foreach方法,该方法从iToble中继承了。每当预期@FunctionalInterface对象时,Nashorn支持传递脚本功能,因此您可以将函数作为消费者参数的参数传递。Java数组上没有这样的java方法,因此第二个for for for for for foreach方法呼叫失败。

请注意,JavaScript Array.prototype.foreach的Nashorn实现是通用的。它在Java阵列,列表上也有效。我调整了您的脚本以使用array.prototype.foreach for Java列表和Java String Array。

var ArrayList = Java.type('java.util.ArrayList');
var list = new ArrayList();
list.add('a');
list.add('b');
list.add('c');
var StringArray = Java.type("java.lang.String[]");
var array = new StringArray(3);
array[0] = "A";
array[1] = "B";
array[2] = "C";
var forEach = Array.prototype.forEach;
forEach.call(list, function(v) { print(v); });
forEach.call(array, function(v) { print(v); });

感谢您的建议。这不仅是关于迭代数组的迭代,而且还希望编写脚本的人们可能期望调用arrays.sort((,arrays.filter((等的函数。

最后,我决定更改所有Java函数,以便通过通过助手函数来调用Java.from((:

,它们返回一个真正的JavaScript数组,而不是本机Java数组,而不是本机Java数组。
private JSObject toJavascript(Object javaObject)
{
    String tmpkey = "tmp"+javaObject.hashCode()+System.currentTimeMillis();
    engine.put(tmpkey, javaObject);
    JSObject jsObject = (JSObject)engine.eval("Java.from("+tmpkey+")");
    engine.put(tmpkey, null);
    return jsObject;
}

可能有一个整洁的事情可以做到这一点,但至少它似乎有效!

最新更新