当使用java的内置javascript解释器时,为什么我可以使用Arrays.forEach()而不是本机数组迭代java List?我有以下测试代码
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没有这样的功能" forEach"在第14行
以下是有效的,但为什么不是array.forEach()?
for (var i=0; i<array.length; ++i)
print(array[i]);
我遇到的问题是我的javascript代码想要调用返回String []的java函数的加载,并且我想处理生成的对象,好像是一个常规的javascript数组。是否有一种更简单的方法来解决这个问题,而不是在java中编写大量的包装器函数来将我的数组转换为ArrayList?
答案 0 :(得分:4)
当您在Java列表上调用forEach时,您正在调用继承自Iterable的List的forEach方法。 Nashorn支持在需要@FunctionalInterface
对象时传递脚本函数,因此您可以将函数作为Consumer参数的参数传递。 Java数组上没有这样的forEach Java方法,因此第二个forEach方法调用失败。
请注意,JavaScript Array.prototype。forEach的Nashorn实现是通用的。它也适用于Java数组,列表。我调整了脚本,将Array.prototype.forEach用于Java List和java String数组。
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); });
答案 1 :(得分:0)
感谢您的建议。它不仅仅是迭代数组,而且编写脚本的人可能希望调用Arrays.sort(),Arrays.filter()等函数。
最后,我决定更改所有Java函数,使它们返回一个真正的JavaScript数组,而不是本机Java数组,方法是通过一个辅助函数来调用Java.from():
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;
}
可能有一个整洁的事情,但至少它似乎工作!