Note: information on this page refers to Ceylon 1.0, not to the current release.

Type mapping rules

On this page we document how Ceylon types are mapped to Java types on the JVM. The Ceylon compiler is responsible for implementing the rules but the rules are largely constructed on the basis of 'the simplest thing that could possibly work'. Even so, the rules are sometimes complex.

Reification

The Ceylon compiler reifies Ceylon types. This means it stores the full type information, including generic type parameters within the compiled code. It does this using Java annotations (with runtime retention). This is why it doesn't matter that the mappings in the table below are not one-to-one: The Ceylon compiler and runtime can always inspect the annotations to determine detailed (Ceylon) type information.

Basic mapping rules

In general the following table is a simplification because the actual mapping rules depend on how the type is being used. For example a Ceylon type may map to one Java type when used in a method return type and a different Java type when used in an extends or satisifes clause.

The mapping to primitive types is overriden by the following situations:

  1. When a type is used as a generic type argument, because primitive types can't be used in this position on the JVM.
  2. When a type is used in a position constrained by actual constraints. For example as a method return or parameter type on an actual method implementation whose formal definition is using a generic type parameter. Same for attribute types with a similar actual constraint.
  3. When a type is used in a position constrained by actual constraints that require the type to be using a different primitive. This is a variant of the previous type of constraint except it happens when you satisfy or extend a Java type which requires that your type be a different primitive. For example int instead of long.

Please note: These mapping rules are subject to change as the compiler develops.

Ceylon type Java type
ceylon.language.Anything java.lang.Object
ceylon.language.Object java.lang.Object
ceylon.language.Basic java.lang.Object
ceylon.language.Null java.lang.Object
ceylon.language.Boolean boolean1
ceylon.language.Boolean? ceylon.language.Boolean
ceylon.language.Integer long1
ceylon.language.Integer? ceylon.language.Integer
ceylon.language.Float double1
ceylon.language.Float? ceylon.language.Float
ceylon.language.Character int1, 2
ceylon.language.Character? ceylon.language.Character
ceylon.language.String java.lang.String1
ceylon.language.String? ceylon.language.String
ceylon.language.Exception ceylon.language.Exception (in instantiations and extends clauses)
java.lang.Exception (in catch clauses)
java.lang.Throwable (everywhere else)
ceylon.language.Sequence ceylon.language.Iterable

All other types are not mapped.

Java mapping rules

In addition, we map the following Java types to certain Ceylon types:

Java type Ceylon type
byte ceylon.language.Integer3
short ceylon.language.Integer
int ceylon.language.Integer
float ceylon.language.Float
char ceylon.language.Character4
boolean[], byte[], short[], int[], long[], float[], double[], char[] java.lang.BooleanArray, java.lang.ByteArray, java.lang.ShortArray, java.lang.IntArray, java.lang.LongArray, java.lang.FloatArray, java.lang.DoubleArray, java.lang.CharArray5
T[] java.lang.ObjectArray<T>5
java.lang.Object ceylon.language.Basic

Notes:

1 Unless used as a type parameter, or in a position constrained by `actual` constraints.
2 In Ceylon, characters are stored as Unicode code-points, thus requiring 32 bits.
3 This is likely to change in the future if we introduce a Ceylon `Byte` type.
4 Java characters can only represent the first half of a Unicode code-point (16 bits).
5 See more info on Java arrays.

See also