Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Converting Script Values to Java

Attila Szegedi edited this pageMar 16, 2021 ·2 revisions

When values (including both primitives and objects) are passed back as parameters to Java methods, they are often converted. Nashorn supports a wide variety of automatic value conversions, that seek to incorporate both the flexibility of ECMAScript value conversion system as well as the rules of Java. In addition, in some situations explicit conversion operations are possible. We describe all below.

Automatic conversions

When a method on a Java object is invoked, the arguments are converted to the formal parameter types of the Java method using all allowed ECMAScript conversions. This can be surprising, as in general, conversions from string to number will succeed according to Standard's section 9.3 "ToNumber" and so on; string to boolean, number to boolean, Object to number, Object to string all work. In detail the supported conversions are as follows:

Java typeConversion
booleanAs perECMAScript 9.2ToBoolean conversion. Colloquially, as if you applied!! to the value.
byte,short,int,float,long,doubleAs perECMAScript 9.3ToNumber conversion. Colloquially, as if you applied+ to the value to obtain a JavaScript number and then if necessary used Java casting to convert to the target type.
charIf the value isnull,(char)0. If the value is a number between 0-65535 then(char)i, wherei is the value of the number truncated to integer. Otherwise the value is converted to a string usingECMAScript 9.8ToString conversion. If the result of the conversion isnull, then(char)0. Otherwise if the string length is not exactly 1, aTypeError is thrown. Otherwise, the first character of the string is returned.
String,CharSequencenull is passed as-is, otherwiseECMAScript 9.8ToString conversion is used.
Numbernull is passed as-is, but the concrete type might be eitherInteger orDouble.
Characteraschar, exceptnull is passed as-is and not converted to(char)0.
Byte,Short,Int,Float,Long,Doublenull is passed as-is, otherwise as for the primitive types. Undefined values are converted to eitherNan for floats and doubles ornull for integer types.
lambda typesIf the type is a Java lambda type (an interface or abstract class with a single method), you can pass in an ECMAScript function and Nashorn will do the right thing, and create an adapter for the lambda type. Nashorn is even more versatile than Java though, you can pass a function for a type that hasmultiple abstract methods, but they all share the same name (the name is overloaded.) In that case, the passed function will be used as the implementation for all the overloads and must analyze the number and types of its parameters to decide which overload was invoked.
Mapnull is passed as-is. Any script object will be passed as-is, as they all implement theMap interface with string keys. This is true of script arrays too. Primitive types cannot be passed (they are not run automatically through ECMAScriptToObject conversion.)
List,Collection,Queue,Dequeuenull is passed as-is. For native script arrays, an adapter is returned that exposes the array. Note that with ECMAScript arrays,push andpop operate at the end of the array, while in JavaDeque they operate on the front of the queue and as such the Java dequeuepush andpop operations will translate tounshift andshift script operations respectively, while JavaaddLast andremoveLast will translate topush andpop. Primitive values and objects that are not arrays can not be passed. It is possible to enforce converting other array-like objects to lists and queues with explicit call toJava.to, see later.
Java array typesScript arrays are converted to Java arrays using per-component conversions. If the target Java array type is multidimensional, components are recursively converted, so it will properly convert arrays-of-arrays etc. Objects that are not native script arrays can not be passed. It is possible to enforce converting other array-like objects to Java arrays with explicit call toJava.to, see later.
Objectif the Java parameter type is justObject, values are passed as they are. JavaScript primitive values are passed asBoolean (for booleans),Number (for numbers), andCharSequence (for strings). Strings are not necessarily a JavaString but they are always aCharSequence. Numbers will usually beInteger orDouble. Script objects will be passed as object implementing both Nashorn'sJSObject interface and also theMap interface. This is true of script arrays too –- if you need arrays to implementList instead, you'll need to useJava.asJSONCompatible explicit conversion method found in the built-inJava global object.

Explicit conversions

The built-inJava object contains two methods useful for explicit specialized conversions to Java types:Java.asJSONCompatible andJava.to.

Java.asJSONCompatible

This method is useful if you need to pass a script array (or an object graph containing script arrays recursively) such that array adapters should exposeList interface instead of theMap interface that is by default exposed by all script objects to Java. The name of the method stems from the fact that various Java JSON libraries typically have this expectation. Unfortunately, it is also impossible for a single Java class to implement bothMap andList interfaces, hence we are providing the developer here with a choice of how to represent script arrays in Java.

Java.to

While Nashorn automatically converts native script arrays (those of script classArray) to either Java arrays or toCollection,List,Queue, andDeque interface, it won't do that for other objects that might still be "array-like". A script object is array-like if it has alength property andpush,pop,shift,unshift, andsplice methods, with the expectation that all of them have same behaviors as the native script arrays. UsingJava.to you can explicitly convert such array-like objects to Java arrays or collections:

varsomeArrayLike= ...javaObj.methodExpectingIntArray(Java.to(someArrayLike,Java.type("int[]"))

If converting to lists or queues, the adapter will callsplice to add or remove elements in the middle of the list,push, andunshift to add elements to the start and end of the list, andpop andshift to remove elements from the start and end of the list.

Note that with ECMAScript arrays,push andpop operate at the end of the array, while in JavaDeque they operate on the front of the queue and as such calls to the Java dequeueaddFirst/push andremoveFirst/pop methods will translate tounshift andshift script methods respectively, while JavaaddLast andremoveLast will translate to scriptpush andpop.

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp