| Java Type | JS Type | Clarification |
|---|---|---|
| boolean | boolean | |
| byte | number | |
| char | number | |
| short | number | |
| int | number | |
| long | goog.math.Long | |
| float | number | |
| double | number | |
| java.lang.Boolean | boolean | null | See Boxing section below |
| java.lang.Byte | java.lang.Byte | null | |
| java.lang.Character | java.lang.Character | null | |
| java.lang.Short | java.lang.Short | null | |
| java.lang.Integer | java.lang.Integer | null | |
| java.lang.Long | goog.math.Long | null | See Boxing section below |
| java.lang.Float | java.lang.Float | null | |
| java.lang.Double | number | null | See Boxing section below |
| java.lang.String | string | null | See Boxing section below |
| java.lang.Object | * | See Boxing section below |
Boxed types
add a noticeable amount of performance overhead to JavaScript. To eliminate this
overhead, J2CL never uses boxed representation for Double, String and Boolean.
Double becomes a JavaScript number, Boolean becomes a JavaScript boolean, and
Long becomes a goog.math.Long. It's not possible to use plain numbers for
boxed Integers because it leads to ambiguity. For example, the instanceof
operator wouldn't be able to distinguish between Integer and Double:
Object foo = new Double(42)
// If both Integer and Double were represented with plain js number then there would be no way
// to perform this runtime check for the type.
if (foo instanceof Integer) {
x--;
} else if (foo instanceof Double) {
x++;
}Note that no such ambiguity exists for primitive ints, which is why they can be represented using a native JavaScript number.
JavaScript natively supports strings and J2CL automatically unboxes Strings. So there is a one-to-one mapping between Java String and the native JavaScript string type.
JavaScript does not natively support integers. J2CL emulates integers using the native JavaScript number type: a 64-bit double. Note that boxed Integers remain boxed, unlike Double and Boolean.
JavaScript natively supports doubles and J2CL automatically unboxes Doubles. So there is a one-to-one mapping between Java Double/double and the native JavaScript number type.
JavaScript does not natively support longs. J2CL emulates longs using the Closure long library: goog.math.Long
There is a one-to-one mapping between Java Long/long and the JavaScript goog.math.Long type.
JavaScript natively supports booleans and J2CL automatically unboxes Booleans. So there is a one-to-one mapping between Java Boolean/boolean and the native JavaScript boolean type.
From J2CL's perspective null and undefined are the same type. If you check
if a value is equal to null then it will return true if the value is null or
undefined.
TODO(rluble): complete the following table
toString() |
equals() |
hashcode() |
getClass() |
|
|---|---|---|---|---|
| Arrays | ||||
| Native arrays | ||||
| JsFunction | ||||
| JsFunction | ||||
| : implementation : : : : : |
- Namespaces on non-native JsMethods are forbidden (i.e. J2CL does not allow to define a method out of its module's scope). GWT allowed this only due to providing a way to export functions to global scope; J2CL relies on goog.export for the same functionality.
- Namespace JsPackage.GLOBAL is special. Native JsTypes within this namespace are considered externs hence no goog.require will be generated for them.
- Instances of
java.lang.Object[]are not stamped.new Object[]{ "a" }in Java and["a"]in JS are effectively same. - instanceof on a class F implementing a @JsFunction interface returns true if and only if the instance is actually an instance of class F.
- Subclasses of classes that have a
@JsConstructorare required to have a@JsConstructor. - The constructor of an anonymous inner class that extends a class with a
@JsConstructoris implicitly a@JsConstructor.