Casting
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.
Refer to the cast table for a quick reference on all allowed casts.
Errors
- If during a cast there exists no equivalent value for the target type.
- If an implicit cast is given, but an explicit cast is required.
Grammar
cast: '(' TYPE ')' expression
Examples
Valid casts.
int i = (int)5L; Map m = new HashMap(); HashMap hm = (HashMap)m;- declare
int i; explicit castlong 5toint 5→int 5; storeint 5toi - declare
Map m; allocateHashMapinstance →HashMap reference; implicit castHashMap referencetoMap reference→Map reference; storeMap referencetom - declare
HashMap hm; load fromm→Map reference; explicit castMap referencetoHashMap reference→HashMap reference; storeHashMap referencetohm
- declare
A 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; long b = a; short c = (short)b; double e = (double)a;- declare
int a; storeint 1toa - declare
long b; load froma→int 1; implicit castint 1tolong 1→long 1; storelong 1tob - declare
short c; load fromb→long 1; explicit castlong 1toshort 1→short 1; storeshort 1value toc - declare
double e; load froma→int 1; explicit castint 1todouble 1.0; storedouble 1.0toe; (note the explicit cast is extraneous since an implicit cast is valid)
- declare
Invalid numeric type casts resulting in errors.
int a = 1.0; int b = 2; byte c = b;- declare
int i; error → cannot implicit castdouble 1.0toint 1; (note an explicit cast is valid) - declare
int b; storeint 2tob - declare byte
c; load fromb→int 2; error → cannot implicit castint 2tobyte 2; (note an explicit cast is valid)
- declare
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; ArrayList y = new ArrayList(); x = y; y = (ArrayList)x; x = (List)y;- declare
List x; store default valuenulltox - declare
ArrayList y; allocateArrayListinstance →ArrayList reference; storeArrayList referencetoy; - load from
y→ArrayList reference; implicit castArrayList referencetoList reference→List reference; storeList referencetox; (noteArrayListis a descendant ofList) - load from
x→List reference; explicit castList referencetoArrayList reference→ArrayList reference; storeArrayList referencetoy; - load from
y→ArrayList reference; explicit castArrayList referencetoList reference→List reference; storeList referencetox; (note the explicit cast is extraneous, and an implicit cast is valid)
- declare
Invalid reference type casts resulting in errors.
List x = new ArrayList(); ArrayList y = x; Map m = (Map)x;- declare
List x; allocateArrayListinstance →ArrayList reference; implicit castArrayList referencetoList reference→List reference; storeList referencetox - declare
ArrayList y; load fromx→List reference; error → cannot implicit castList referencetoArrayList reference; (note an explicit cast is valid sinceArrayListis a descendant ofList) - declare
ArrayList y; load fromx→List reference; error → cannot explicit castList referencetoMap reference; (note no cast is valid since neitherListnorMapis a descendant of the other)
- declare
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
deftype.def d0 = 3; d0 = new ArrayList(); Object o = new HashMap(); def d1 = o; int i = d1.size();- declare
def d0; implicit castint 3todef; storeint 3tod0 - allocate
ArrayListinstance →ArrayList reference; implicit castArrayList referencetodef→def; storedeftod0 - declare
Object o; allocateHashMapinstance →HashMap reference; implicit castHashMap referencetoObject reference→Object reference; storeObject referencetoo - declare
def d1; load fromo→Object reference; implicit castObject referencetodef→def; storedeftod1 - declare
int i; load fromd1→def; implicit castdeftoHashMap reference→ HashMap reference; callsizeonHashMap reference→int 0; storeint 0toi; (notedefwas implicit cast toHashMap referencesinceHashMapis the child-most descendant type value that thedef` type value represents)
- declare
Valid dynamic type casts with an original
deftype to any target type.def d = 1.0; int i = (int)d; d = 1; float f = d; d = new ArrayList(); List l = d;- declare
def d; implicit castdouble 1.0todef→def; storedeftod - declare
int i; load fromd→def; implicit castdeftodouble 1.0→double 1.0; explicit castdouble 1.0toint 1→int 1; storeint 1toi; (note the explicit cast is necessary since adoubletype value is not converted to aninttype value implicitly) - store
int 1tod; (note the switch in the typedrepresents fromdoubletoint) - declare
float i; load fromd→def; implicit castdeftoint 1→int 1; implicit castint 1tofloat 1.0→float 1.0; storefloat 1.0tof - allocate
ArrayListinstance →ArrayList reference; storeArrayList referencetod; (note the switch in the typedrepresents frominttoArrayList) - declare
List l; load fromd→def; implicit castdeftoArrayList reference→ArrayList reference; implicit castArrayList referencetoList reference→List reference; storeList referencetol
- declare
Invalid dynamic type casts resulting in errors.
def d = 1; short s = d; d = new HashMap(); List l = d;- declare
def d; implicit castint 1todef→def; storedeftod - declare
short s; load fromd→def; implicit castdeftoint 1→int 1; error → cannot implicit castint 1toshort 1; (note an explicit cast is valid) - allocate
HashMapinstance →HashMap reference; implicit castHashMap referencetodef→def; storedeftod - declare
List l; load fromd→def; implicit castdeftoHashMap reference; error → cannot implicit castHashMap referencetoList reference; (note no cast is valid since neitherHashMapnorListis a descendant of the other)
- declare
Use the cast operator to convert a String type value into a char type value.
Errors
- If the
Stringtype value isn’t one character in length. - If the
Stringtype value isnull.
Examples
Casting string literals into
chartype values.char c = (char)"C"; c = (char)'c';- declare
char c; explicit castString "C"tochar C→char C; storechar Ctoc - explicit cast
String 'c'tochar c→char c; storechar ctoc
- declare
Casting a
Stringreference into achartype value.String s = "s"; char c = (char)s;- declare
String s; storeString "s"tos; - declare
char cload froms→String "s"; explicit castString "s"tochar s→char s; storechar stoc
- declare
Use the cast operator to convert a char type value into a String type value.
Examples
Casting a
Stringreference into achartype value.char c = 65; String s = (String)c;- declare
char c; storechar 65toc; - declare
String sload fromc→char A; explicit castchar AtoString "A"→String "A"; storeString "A"tos
- declare
Boxing 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:
- Conversions between a
deftype and a primitive type are implicitly boxed/unboxed as necessary, though this is referred to as an implicit cast throughout the documentation. - Method/function call arguments are implicitly boxed/unboxed as necessary.
- A primitive type value is implicitly boxed when a reference type method is called on it.
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
- If an explicit cast is made to box/unbox a primitive type.
Examples
Uses of implicit boxing/unboxing.
List l = new ArrayList(); l.add(1); Integer I = Integer.valueOf(0); int i = l.get(i);- declare
List l; allocateArrayListinstance →ArrayList reference; storeArrayList referencetol; - load from
l→List reference; implicit castint 1todef→def; calladdonList referencewith arguments (def); (note internallyint 1is boxed toInteger 1to store as adeftype value) - declare
Integer I; callvalueOfonIntegerwith arguments of (int 0) →Integer 0; storeInteger 0toI; - declare
int i; load fromI→Integer 0; unboxInteger 0→int 0; load froml→List reference; callgetonList referencewith arguments (int 0) →def; implicit castdeftoint 1→int 1; storeint 1toi; (note internallyint 1is unboxed fromInteger 1when loaded from adeftype value)
- declare
Uses of invalid boxing/unboxing resulting in errors.
Integer x = 1; Integer y = (Integer)1; int a = Integer.valueOf(1); int b = (int)Integer.valueOf(1);- declare
Integer x; error → cannot implicit boxint 1toInteger 1during assignment - declare
Integer y; error → cannot explicit boxint 1toInteger 1during assignment - declare
int a; callvalueOfonIntegerwith arguments of (int 1) →Integer 1; error → cannot implicit unboxInteger 1toint 1during assignment - declare
int a; callvalueOfonIntegerwith arguments of (int 1) →Integer 1; error → cannot explicit unboxInteger 1toint 1during assignment
- declare
Promotion 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
- If a specific operation cannot find an allowed promotion type for the type(s) of value(s) given.
Examples
Uses of promotion.
double d = 2 + 2.0; def x = 1; float f = x + 2.0F;- declare
double d; promoteint 2anddouble 2.0 @0: resultdouble; implicit castint 2todouble 2.0 @1→double 2.0 @1; adddouble 2.0 @1anddouble 2.0 @0→double 4.0; storedouble 4.0tod - declare
def x; implicit castint 1todef→def; storedeftox; - declare
float f; load fromx→def; implicit castdeftoint 1→int 1; promoteint 1andfloat 2.0: resultfloat; implicit castint 1tofloat 1.0→float1.0; addfloat 1.0andfloat 2.0→float 3.0; storefloat 3.0tof; (note this example illustrates promotion done at run-time as promotion done at compile-time would have resolved to adef` type value)
- declare
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 | @ | @ | @ | - | - | - | - | - | - | - | - | @ | @ | @ | @ | @ | @ | @ | @ | @ |