admin管理员组文章数量:1302278
When using java's built-in javascript interpreter, why can I iterate over a java List using Arrays.forEach() but not over a native array? I have the following test code
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); });
which I'd expect to print out
a b c A B C
but instead I get
a b c
TypeError: [Ljava.lang.String;@644e4fbf has no such function "forEach" in at line number 14
The following works, but why not array.forEach() ?
for (var i=0; i<array.length; ++i)
print(array[i]);
The issue I have is that my javascript code wants to call a load of java functions that return a String[], and I want to deal with the resulting object as if was a regular javascript array. Is there an easier way to fix this than writing loads of wrapper functions in java that convert my arrays to an ArrayList?
When using java's built-in javascript interpreter, why can I iterate over a java List using Arrays.forEach() but not over a native array? I have the following test code
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); });
which I'd expect to print out
a b c A B C
but instead I get
a b c
TypeError: [Ljava.lang.String;@644e4fbf has no such function "forEach" in at line number 14
The following works, but why not array.forEach() ?
for (var i=0; i<array.length; ++i)
print(array[i]);
The issue I have is that my javascript code wants to call a load of java functions that return a String[], and I want to deal with the resulting object as if was a regular javascript array. Is there an easier way to fix this than writing loads of wrapper functions in java that convert my arrays to an ArrayList?
Share Improve this question asked Jun 29, 2017 at 19:10 RolfRolf 6621 gold badge6 silver badges17 bronze badges 1-
You can use the (extremely unfortunate, in my opinion) Nashorn
for each (var element in array)
syntax. (Taken from Mozilla extensions that have, I think, been quashed in modern Firefox.) – Pointy Commented Jun 29, 2017 at 19:21
2 Answers
Reset to default 8When you call forEach on a Java List, you are invoking the List's forEach method inherited from Iterable. Nashorn supports passing a script function whenever a @FunctionalInterface
object is expected and so you can pass function as argument for the Consumer parameter. There is no such forEach Java method on Java arrays and hence the second forEach method call fails.
Note that the Nashorn implementation of the JavaScript Array.prototype.forEach is generic. It works on Java arrays, lists as well. I adjusted your script to use Array.prototype.forEach for both Java List and 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); });
Thanks for the suggestions. It's not just about iterating over the array but also that people writing scripts might expect to call functions like Arrays.sort(), Arrays.filter() etc.
In the end I decided to change all the Java functions so they return a true JavaScript array, rather than a native Java array, by passing them through a helper function to call 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;
}
There's probably a neater to do this but at least it seems to work!
本文标签: javascriptIterating over array with NashornStack Overflow
版权声明:本文标题:javascript - Iterating over array with Nashorn - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741673597a2391748.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论