Annotation Interface JS.Coerce

Enclosing class:
JS

@Retention(RUNTIME) @Target(METHOD) public static @interface JS.Coerce
When this annotation is used together with the JS annotation, the arguments and return values of the respective method undergo implicit Java-to-JavaScript and JavaScript-to-Java conversions. When the JS.Coerce annotation is present, Java-value arguments to JS-annotated methods are implicitly converted (coerced) to the corresponding JavaScript type (and more broadly, they are implicitly converted when JavaScript code calls a Java method that has the JS.Coerce annotation, and that method returns a value). These conversions are done in a way such that no information is dropped -- for example, a Java byte value is coerced to a JavaScript Number value, which is a wider type. The following Java types are coerced to JavaScript values as follows:
  • boolean and Boolean are converted to a JavaScript Boolean.
  • byte (and Byte), short (and Short), char (and Character), int (and Integer), float (and Float), double (and Double), are converted to a JavaScript Number.
  • long, Long and BigInteger are converted to a JavaScript BigInt.
  • String is converted to a JavaScript String.
  • Any functional-interface object (whose class implements exactly one single abstract method as defined by the FunctionalInterface annotation) is converted to a JavaScript Function.
  • A primitive array is converted to corresponding JavaScript typed arrays. Concretely, an array of type boolean[] is converted to a JavaScript Uint8Array, a byte[] array to a JavaScript Int8Array, a short[] array to a JavaScript Int16Array, a char[] array to a JavaScript Uint16Array, a int[] array to a JavaScript Int32Array, a float[] array to a JavaScript Float32Array, a long[] array to a JavaScript BigInt64Array, and a double[] array to a JavaScript Float64Array.
  • All other values are not coerced -- subtypes of the Java JSValue class are converted to corresponding JavaScript values, and other objects are converted to JavaScript proxies.
When the JS.Coerce annotation is present, JavaScript return values of JS-annotated methods, which originate from JavaScript code, are implicitly converted (coerced) to the corresponding Java values (and more broadly, they are implicitly converted when JavaScript code passes JavaScript arguments to a Java method that has JS.Coerce annotation). The conversion is driven by the type that Java expects. For example, if the return type of a JS-annotated method is double, then a JavaScript Number will be converted to a double. If the return type is int, then the JavaScript Number will be converted to an int, even though this may truncate the original JavaScript value. However, only certain JavaScript values can be converted to certain Java types -- for example, a JavaScript String is not converted to a Java int, and the attempt to return a JavaScript String from a JS-annotated method whose return type is int will throw a ClassCastException. The following JavaScript types are coerced to the expected Java types as follows:
  • JavaScript Boolean can be coerced to a Java boolean and Boolean.
  • JavaScript Number and BigInt can be coerced to a Java byte (and Byte), short (and Short), char (and Character), int (and Integer), long (and Long), float (and Float), and double (and Double), BigInteger and BigDecimal.
  • JavaScript String can be coerced to a Java String.
  • JavaScript typed array can be coerced to a corresponding Java primitive array, if there is one. Concretely, a JavaScript UInt8Array can be coerced to a boolean[]. A JavaScript Int8Array can be coerced to a byte[] array. A JavaScript Int16Array can be coerced to a short[], a Uint16Array can be coerced to a char[], a Int32Array can be coerced to a int[], a Float32Array can be coerced to a float[], a BigInt64Array can be coerced to a long[], and a Float64Array can be coerced to a double[].
  • JavaScript Object can be coerced to any Java class that is a subclass of JSObject if that class conforms to that JavaScript object.
  • All other values are not coerced -- they are converted to the corresponding Java JSValue class, with the exception of JavaScript Proxy objects that wrap Java objects (those are converted back to the original Java objects). A mismatch with the user-ascribed type will cause a ClassCastException.
When an object is mutable, the coercions maintain the property that the state-change in Java is reflected in the corresponding JavaScript object, and vice versa. For immutable objects, the object identity is not preserved when the object is passed from Java to JavaScript and then back again (for example, if Java passes a java.lang.Integer to JavaScript, and JavaScript returns that object back, the returned integer object may not be reference-equal to the original integer object).