Passing Java lists into JS

Tim Fox timvolpe at gmail.com
Thu Nov 27 11:18:04 UTC 2014


On 27/11/14 10:33, Attila Szegedi wrote:
> Nashorn explicitly allows [] operator on java lists and it also supports for…in on them. ".length" is also supported since 8u20, see <https://bugs.openjdk.java.net/browse/JDK-8039387>.
>
> We indeed don't implicitly convert Lists into JS Array objects in Nashorn. The reason is that JS Array has a Java array as backing storage; wrapping a large list would incur a lot of copying.

To avoid the copying, could the Nashorn JS Array implementation be 
changed so it backs either:

a) A Java Array (as it does currently) - this would the case if you 
created the JS array directly in JS code.
b) A Java List - this would be the case if a List was passed from Java 
to JS, providing the user with a JS array

Then we can have our cake and eat it? I.e. we have a real JS Array 
object (not a half way house with some of the functions and properties 
but not all), and no copying overhead.

>   You can use "Java.from(someObject.provideList())" to explicitly convert a Java List to a JS array. We think it's better to provide an explicit conversion API than incur a linear conversion cost whenever a List object passes into the JS context.
> The Java.from created copy is shallow; if you have a List of Lists, the nested List objects are not converted.
>
> Typically you'll want to create a real Array if you want to use Array functionality that points beyond [], .length, and for…in, e.g. JS Array comprehension operations (arguably, we *could* implement even those so that Array.prototype.forEach.call(javaList, ...) works as expected, but we aren't there yet.)
>
> Attila.
>
> On Nov 27, 2014, at 10:41 AM, Tim Fox <timvolpe at gmail.com> wrote:
>
>> Hello again,
>>
>> I am a bit confused about how Lists passed from Java into JS are converted.
>>
>> I have a Java class as follows:
>>
>> public class SomeClass {
>>
>>    public List<String> provideList() {
>>      List<String> list = new ArrayList<>();
>>      list.add("foo");
>>      list.add("bar");
>>      return list;
>>    }
>> }
>>
>> I call this from JavaScript:
>>
>> var io = Packages.io;
>> var someObject = new io.vertx.scratchpad.SomeClass();
>>
>> var arr = someObject.provideList();
>>
>> console.log(arr[0]); // prints: foo
>> console.log(typeof arr.length); // undefined
>> console.log(arr instanceof Array); // false
>>
>> I was under the impression that Nashorn automatically converted Java lists passed into JS into JS Arrays.
>>
>> The object arr returned in some ways resembles a JavaScript array - the operators [] and []= work on it, however it doesn't have the array property "length" and it's not an instanceof Array.
>>
>> Can anyone clarify to me what this object is? Any reason why Nashorn doesn't just wrap it as a real JS Array?
>>
>> Cheers



More information about the nashorn-dev mailing list