docs/reference/scripting-languages/painless/painless-casting.md
A cast converts the value of an original type to the equivalent value of a target type. An implicit cast infers the target type and automatically occurs during certain operations. An explicit cast specifies the target type and forcefully occurs as its own operation. Use the cast operator '()' to specify an explicit cast. You can also check out the type casting tutorial for related examples, and for help with troubleshooting refer to "type casting issues" in the Troubleshooting section.
Refer to the cast table for a quick reference on all allowed casts. To help resolve any issues, check Debug type casting errors in Painless.
Errors
Grammar
cast: '(' TYPE ')' expression
Examples
Valid casts
int i = (int)5L; <1>
Map m = new HashMap(); <2>
HashMap hm = (HashMap)m; <3>
int i; explicit cast long 5 to int 5 → int 5; store int 5 to iMap m; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to Map reference → Map reference; store Map reference to mHashMap hm; load from m → Map reference; explicit cast Map reference to HashMap reference → HashMap reference; store HashMap reference to hmA numeric type cast converts the value of an original numeric type to the equivalent value of a target numeric type. A cast between two numeric type values results in data loss when the value of the original numeric type is larger than the target numeric type can accommodate. A cast between an integer type value and a floating point type value can result in precision loss.
The allowed casts for values of each numeric type are shown as a row in the following table:
| byte | short | char | int | long | float | double | |
| byte | implicit | implicit | implicit | implicit | implicit | implicit | |
| short | explicit | explicit | implicit | implicit | implicit | implicit | |
| char | explicit | explicit | implicit | implicit | implicit | implicit | |
| int | explicit | explicit | explicit | implicit | implicit | implicit | |
| long | explicit | explicit | explicit | explicit | implicit | implicit | |
| float | explicit | explicit | explicit | explicit | explicit | implicit | |
| double | explicit | explicit | explicit | explicit | explicit | explicit |
Examples
Valid numeric type casts
int a = 1; <1>
long b = a; <2>
short c = (short)b; <3>
double e = (double)a; <4>
int a; store int 1 to along b; load from a → int 1; implicit cast int 1 to long 1 → long 1; store long 1 to bshort c; load from b → long 1; explicit cast long 1 to short 1 → short 1; store short 1 value to cdouble e; load from a → int 1; explicit cast int 1 to double 1.0; store double 1.0 to e; (note the explicit cast is extraneous since an implicit cast is valid)Invalid numeric type casts resulting in errors
int a = 1.0; // error <1>
int b = 2; <2>
byte c = b; // error <3>
int i; error → cannot implicit cast double 1.0 to int 1; (note an explicit cast is valid)int b; store int 2 to bc; load from b → int 2; error → cannot implicit cast int 2 to byte 2; (note an explicit cast is valid)A reference type cast converts the value of an original reference type to the equivalent value of a target reference type. An implicit cast between two reference type values is allowed when the original reference type is a descendant of the target type. An explicit cast between two reference type values is allowed when the original type is a descendant of the target type or the target type is a descendant of the original type.
Examples
Valid reference type casts
List x; <1>
ArrayList y = new ArrayList(); <2>
x = y; <3>
y = (ArrayList)x; <4>
x = (List)y; <5>
List x; store default value null to xArrayList y; allocate ArrayList instance → ArrayList reference; store ArrayList reference to y;y → ArrayList reference; implicit cast ArrayList reference to List reference → List reference; store List reference to x; (note ArrayList is a descendant of List)x → List reference; explicit cast List reference to ArrayList reference → ArrayList reference; store ArrayList reference to y;y → ArrayList reference; explicit cast ArrayList reference to List reference → List reference; store List reference to x; (note the explicit cast is extraneous, and an implicit cast is valid)Invalid reference type casts resulting in errors
List x = new ArrayList(); <1>
ArrayList y = x; // error <2>
Map m = (Map)x; // error <3>
List x; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List reference → List reference; store List reference to xArrayList y; load from x → List reference; error → cannot implicit cast List reference to ArrayList reference; (note an explicit cast is valid since ArrayList is a descendant of List)ArrayList y; load from x → List reference; error → cannot explicit cast List reference to Map reference; (note no cast is valid since neither List nor Map is a descendant of the other)A dynamic (def) type cast converts the value of an original def type to the equivalent value of any target type or converts the value of any original type to the equivalent value of a target def type.
An implicit cast from any original type value to a def type value is always allowed. An explicit cast from any original type value to a def type value is always allowed but never necessary.
An implicit or explicit cast from an original def type value to any target type value is allowed if and only if the cast is normally allowed based on the current type value the def type value represents.
Examples
Valid dynamic type casts with any original type to a target def type
def d0 = 3; <1>
d0 = new ArrayList(); <2>
Object o = new HashMap(); <3>
def d1 = o; <4>
int i = d1.size(); <5>
def d0; implicit cast int 3 to def; store int 3 to d0ArrayList instance → ArrayList reference; implicit cast ArrayList reference to def → def; store def to d0Object o; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to Object reference → Object reference; store Object reference to odef d1; load from o → Object reference; implicit cast Object reference to def → def; store def to d1int i; load from d1 → def; implicit cast def to HashMap reference → HashMap reference; call sizeonHashMap reference→int 0; store int 0toi; (note defwas implicit cast toHashMap referencesinceHashMapis the child-most descendant type value that thedef` type value represents)Valid dynamic type casts with an original def type to any target type
def d = 1.0; <1>
int i = (int)d; <2>
d = 1; <3>
float f = d; <4>
d = new ArrayList(); <5>
List l = d; <6>
def d; implicit cast double 1.0 to def → def; store def to dint i; load from d → def; implicit cast def to double 1.0 → double 1.0; explicit cast double 1.0 to int 1 → int 1; store int 1 to i; (note the explicit cast is necessary since a double type value is not converted to an int type value implicitly)int 1 to d; (note the switch in the type d represents from double to int)float i; load from d → def; implicit cast def to int 1 → int 1; implicit cast int 1 to float 1.0 → float 1.0; store float 1.0 to fArrayList instance → ArrayList reference; store ArrayList reference to d; (note the switch in the type d represents from int to ArrayList)List l; load from d → def; implicit cast def to ArrayList reference → ArrayList reference; implicit cast ArrayList reference to List reference → List reference; store List reference to lInvalid dynamic type casts resulting in errors
def d = 1; <1>
short s = d; // error <2>
d = new HashMap(); <3>
List l = d; // error <4>
def d; implicit cast int 1 to def → def; store def to dshort s; load from d → def; implicit cast def to int 1 → int 1; error → cannot implicit cast int 1 to short 1; (note an explicit cast is valid)HashMap instance → HashMap reference; implicit cast HashMap reference to def → def; store def to dList l; load from d → def; implicit cast def to HashMap reference; error → cannot implicit cast HashMap reference to List reference; (note no cast is valid since neither HashMap nor List is a descendant of the other)Use the cast operator to convert a String type value into a char type value.
Errors
String type value isn’t one character in length.String type value is null.Examples
Casting string literals into char type values
char c = (char)"C"; <1>
c = (char)'c'; <2>
char c; explicit cast String "C" to char C → char C; store char C to cString 'c' to char c → char c; store char c to cCasting a String reference into a char type value
String s = "s"; <1>
char c = (char)s; <2>
String s; store String "s" to s;char c load from s → String "s"; explicit cast String "s" to char s → char s; store char s to cUse the cast operator to convert a char type value into a String type value.
Examples
Casting a String reference into a char type value
char c = 65; <1>
String s = (String)c; <2>
char c; store char 65 to c;String s load from c → char A; explicit cast char A to String "A" → String "A"; store String "A" to sBoxing is a special type of cast used to convert a primitive type to its corresponding reference type. Unboxing is the reverse used to convert a reference type to its corresponding primitive type.
Implicit boxing/unboxing occurs during the following operations:
def type and a primitive type are implicitly boxed/unboxed as necessary, though this is referred to as an implicit cast throughout the documentation.Explicit boxing/unboxing is not allowed. Use the reference type API to explicitly convert a primitive type value to its respective reference type value and vice versa.
Errors
Examples
Uses of implicit boxing/unboxing
List l = new ArrayList(); <1>
l.add(1); <2>
Integer I = Integer.valueOf(0); <3>
int i = l.get(i); <4>
List l; allocate ArrayList instance → ArrayList reference; store ArrayList reference to l;l → List reference; implicit cast int 1 to def → def; call add on List reference with arguments (def); (note internally int 1 is boxed to Integer 1 to store as a def type value)Integer I; call valueOf on Integer with arguments of (int 0) → Integer 0; store Integer 0 to I;int i; load from I → Integer 0; unbox Integer 0 → int 0; load from l → List reference; call get on List reference with arguments (int 0) → def; implicit cast def to int 1 → int 1; store int 1 to i; (note internally int 1 is unboxed from Integer 1 when loaded from a def type value)Uses of invalid boxing/unboxing resulting in errors.
Integer x = 1; // error <1>
Integer y = (Integer)1; // error <2>
int a = Integer.valueOf(1); // error <3>
int b = (int)Integer.valueOf(1); // error <4>
Integer x; error → cannot implicit box int 1 to Integer 1 during assignmentInteger y; error → cannot explicit box int 1 to Integer 1 during assignmentint a; call valueOf on Integer with arguments of (int 1) → Integer 1; error → cannot implicit unbox Integer 1 to int 1 during assignmentint a; call valueOf on Integer with arguments of (int 1) → Integer 1; error → cannot explicit unbox Integer 1 to int 1 during assignmentPromotion is when a single value is implicitly cast to a certain type or multiple values are implicitly cast to the same type as required for evaluation by certain operations. Each operation that requires promotion has a promotion table that shows all required implicit casts based on the type(s) of value(s). A value promoted to a def type at compile-time is promoted again at run-time based on the type the def value represents.
Errors
Examples
Uses of promotion
double d = 2 + 2.0; <1>
def x = 1; <2>
float f = x + 2.0F; <3>
double d; promote int 2 and double 2.0 @0: result double; implicit cast int 2 to double 2.0 @1 → double 2.0 @1; add double 2.0 @1 and double 2.0 @0 → double 4.0; store double 4.0 to ddef x; implicit cast int 1 to def → def; store def to x;float f; load from x → def; implicit cast def to int 1 → int 1; promote int 1 and float 2.0: result float; implicit cast int 1 to float 1.0 → float 1.0; add float 1.0andfloat 2.0→float 3.0; store float 3.0tof; (note this example illustrates promotion done at run-time as promotion done at compile-time would have resolved to a def` type value)The following tables show all allowed casts. Read the tables row by row, where the original type is shown in the first column, and each subsequent column indicates whether a cast to the specified target type is implicit (I), explicit (E), boxed/unboxed for methods only (A), a reference type cast (@), or is not allowed (-). See reference type casting for allowed reference type casts.
Primitive/Reference Types
| O | N | T | b | y | s | c | i | j | f | d | B | Y | S | C | I | J | F | D | R | def | |
| Object ( O ) | @ | @ | - | - | - | - | - | - | - | - | @ | @ | @ | @ | @ | @ | @ | @ | @ | I | |
| Number ( N ) | I | - | - | - | - | - | - | - | - | - | - | @ | @ | - | @ | @ | @ | @ | @ | I | |
| String ( T ) | I | - | - | - | - | - | - | - | - | - | - | - | - | E | - | - | - | - | - | I | |
| boolean ( b ) | A | - | - | - | - | - | - | - | - | - | A | - | - | - | - | - | - | - | - | I | |
| byte ( y ) | A | A | - | - | I | E | I | I | I | I | - | A | A | - | A | A | A | A | - | I | |
| short ( s ) | A | A | - | - | E | E | I | I | I | I | - | - | A | - | A | A | A | A | - | I | |
| char ( c ) | A | - | E | - | E | E | I | I | I | I | - | - | - | A | A | A | A | A | - | I | |
| int ( i ) | A | A | - | - | E | E | E | I | I | I | - | - | - | - | A | A | A | A | - | I | |
| long ( j ) | A | A | - | - | E | E | E | E | I | I | - | - | - | - | - | A | A | A | - | I | |
| float ( f ) | A | A | - | - | E | E | E | E | E | I | - | - | - | - | - | - | A | A | - | I | |
| double ( d ) | A | A | - | - | E | E | E | E | E | E | - | - | - | - | - | - | - | A | - | I | |
| Boolean ( B ) | A | - | - | A | - | - | - | - | - | - | - | - | - | - | - | - | - | - | @ | I | |
| Byte ( Y ) | A | I | - | - | A | A | - | A | A | A | A | - | A | - | A | A | A | A | @ | I | |
| Short ( S ) | A | I | - | - | - | A | - | A | A | A | A | - | - | - | A | A | A | A | @ | I | |
| Character ( C ) | A | - | - | - | - | - | A | A | A | A | A | - | - | - | A | A | A | A | @ | I | |
| Integer ( I ) | A | - | - | - | - | - | - | A | A | A | A | - | - | - | - | A | A | A | @ | I | |
| Long ( J ) | A | - | - | - | - | - | - | - | A | A | A | - | - | - | - | - | A | A | @ | I | |
| Float ( F ) | A | - | - | - | - | - | - | - | - | A | A | - | - | - | - | - | - | A | @ | I | |
| Double ( D ) | A | - | - | - | - | - | - | - | - | - | A | - | - | - | - | - | - | - | @ | I | |
| Reference ( R ) | I | @ | @ | - | - | - | - | - | - | - | - | @ | @ | @ | @ | @ | @ | @ | @ | @ | I |
def Type
| O | N | T | b | y | s | c | i | j | f | d | B | Y | S | C | I | J | F | D | R | |
| def as String | I | - | I | - | - | - | E | - | - | - | - | - | - | - | E | - | - | - | - | @ |
| def as boolean/Boolean | I | - | - | I | - | - | - | - | - | - | - | I | - | - | - | - | - | - | - | @ |
| def as byte/Byte | I | - | - | - | I | I | E | I | I | I | I | - | I | I | E | I | I | I | I | @ |
| def as short/Short | I | - | - | - | E | I | E | I | I | I | I | - | E | I | E | I | I | I | I | @ |
| def as char/Character | I | - | - | - | E | E | I | I | I | I | I | - | E | E | I | I | I | I | I | @ |
| def as int/Integer | I | - | - | - | E | E | E | I | I | I | I | - | E | E | E | I | I | I | I | @ |
| def as long/Long | I | - | - | - | E | E | E | E | I | I | I | - | E | E | E | E | I | I | I | @ |
| def as float/Float | I | - | - | - | E | E | E | E | E | I | I | - | E | E | E | E | E | I | I | @ |
| def as double/Double | I | - | - | - | E | E | E | E | E | E | I | - | E | E | E | E | E | E | I | @ |
| def as Reference | @ | @ | @ | - | - | - | - | - | - | - | - | @ | @ | @ | @ | @ | @ | @ | @ | @ |