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.
  • 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 Object can be coerced to JSObject or any of its subtypes.
  • 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).