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; 1 Map m = new HashMap(); 2 HashMap hm = (HashMap)m; 3
- declare
int i
; explicit castlong 5
toint 5
→int 5
; storeint 5
toi
- declare
Map m
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tom
- declare
HashMap hm
; load fromm
→Map reference
; explicit castMap reference
toHashMap reference
→HashMap reference
; storeHashMap reference
tohm
- 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; 1 long b = a; 2 short c = (short)b; 3 double e = (double)a; 4
- declare
int a
; storeint 1
toa
- declare
long b
; load froma
→int 1
; implicit castint 1
tolong 1
→long 1
; storelong 1
tob
- declare
short c
; load fromb
→long 1
; explicit castlong 1
toshort 1
→short 1
; storeshort 1
value toc
- declare
double e
; load froma
→int 1
; explicit castint 1
todouble 1.0
; storedouble 1.0
toe
; (note the explicit cast is extraneous since an implicit cast is valid)
- declare
Invalid numeric type casts resulting in errors.
int a = 1.0;1 int b = 2; 2 byte c = b; 3
- declare
int i
; error → cannot implicit castdouble 1.0
toint 1
; (note an explicit cast is valid) - declare
int b
; storeint 2
tob
- declare byte
c
; load fromb
→int 2
; error → cannot implicit castint 2
tobyte 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; 1 ArrayList y = new ArrayList(); 2 x = y; 3 y = (ArrayList)x; 4 x = (List)y; 5
- declare
List x
; store default valuenull
tox
- declare
ArrayList y
; allocateArrayList
instance →ArrayList reference
; storeArrayList reference
toy
; - load from
y
→ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
; (noteArrayList
is a descendant ofList
) - load from
x
→List reference
; explicit castList reference
toArrayList reference
→ArrayList reference
; storeArrayList reference
toy
; - load from
y
→ArrayList reference
; explicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
; (note the explicit cast is extraneous, and an implicit cast is valid)
- declare
Invalid reference type casts resulting in errors.
List x = new ArrayList(); 1 ArrayList y = x; 2 Map m = (Map)x; 3
- declare
List x
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
- declare
ArrayList y
; load fromx
→List reference
; error → cannot implicit castList reference
toArrayList reference
; (note an explicit cast is valid sinceArrayList
is a descendant ofList
) - declare
ArrayList y
; load fromx
→List reference
; error → cannot explicit castList reference
toMap reference
; (note no cast is valid since neitherList
norMap
is 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
def
type.def d0 = 3; 1 d0 = new ArrayList(); 2 Object o = new HashMap(); 3 def d1 = o; 4 int i = d1.size(); 5
- declare
def d0
; implicit castint 3
todef
; storeint 3
tod0
- allocate
ArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
tod0
- declare
Object o
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toObject reference
→Object reference
; storeObject reference
too
- declare
def d1
; load fromo
→Object reference
; implicit castObject reference
todef
→def
; storedef
tod1
- declare
int i
; load fromd1
→def
; implicit castdef
toHashMap reference
→ HashMap reference; call
sizeon
HashMap reference→
int 0; store
int 0to
i; (note
defwas implicit cast to
HashMap referencesince
HashMapis the child-most descendant type value that the
def` type value represents)
- declare
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
- declare
def d
; implicit castdouble 1.0
todef
→def
; storedef
tod
- declare
int i
; load fromd
→def
; implicit castdef
todouble 1.0
→double 1.0
; explicit castdouble 1.0
toint 1
→int 1
; storeint 1
toi
; (note the explicit cast is necessary since adouble
type value is not converted to anint
type value implicitly) - store
int 1
tod
; (note the switch in the typed
represents fromdouble
toint
) - declare
float i
; load fromd
→def
; implicit castdef
toint 1
→int 1
; implicit castint 1
tofloat 1.0
→float 1.0
; storefloat 1.0
tof
- allocate
ArrayList
instance →ArrayList reference
; storeArrayList reference
tod
; (note the switch in the typed
represents fromint
toArrayList
) - declare
List l
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tol
- declare
Invalid dynamic type casts resulting in errors.
def d = 1; 1 short s = d; 2 d = new HashMap(); 3 List l = d; 4
- declare
def d
; implicit castint 1
todef
→def
; storedef
tod
- declare
short s
; load fromd
→def
; implicit castdef
toint 1
→int 1
; error → cannot implicit castint 1
toshort 1
; (note an explicit cast is valid) - allocate
HashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
; storedef
tod
- declare
List l
; load fromd
→def
; implicit castdef
toHashMap reference
; error → cannot implicit castHashMap reference
toList reference
; (note no cast is valid since neitherHashMap
norList
is a descendant of the other)
- declare
Use the cast operator to convert a String
type value into a char
type value.
Errors
- If the
String
type value isn’t one character in length. - If the
String
type value isnull
.
Examples
Casting string literals into
char
type values.char c = (char)"C"; 1 c = (char)'c'; 2
- declare
char c
; explicit castString "C"
tochar C
→char C
; storechar C
toc
- explicit cast
String 'c'
tochar c
→char c
; storechar c
toc
- declare
Casting a
String
reference into achar
type value.String s = "s"; 1 char c = (char)s; 2
- declare
String s
; storeString "s"
tos
; - declare
char c
load froms
→String "s"
; explicit castString "s"
tochar s
→char s
; storechar s
toc
- declare
Use the cast operator to convert a char
type value into a String
type value.
Examples
Casting a
String
reference into achar
type value.char c = 65; 1 String s = (String)c; 2
- declare
char c
; storechar 65
toc
; - declare
String s
load fromc
→char A
; explicit castchar A
toString "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
def
type 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(); 1 l.add(1); 2 Integer I = Integer.valueOf(0); 3 int i = l.get(i); 4
- declare
List l
; allocateArrayList
instance →ArrayList reference
; storeArrayList reference
tol
; - load from
l
→List reference
; implicit castint 1
todef
→def
; calladd
onList reference
with arguments (def
); (note internallyint 1
is boxed toInteger 1
to store as adef
type value) - declare
Integer I
; callvalueOf
onInteger
with arguments of (int 0
) →Integer 0
; storeInteger 0
toI
; - declare
int i
; load fromI
→Integer 0
; unboxInteger 0
→int 0
; load froml
→List reference
; callget
onList reference
with arguments (int 0
) →def
; implicit castdef
toint 1
→int 1
; storeint 1
toi
; (note internallyint 1
is unboxed fromInteger 1
when loaded from adef
type value)
- declare
Uses of invalid boxing/unboxing resulting in errors.
Integer x = 1; 1 Integer y = (Integer)1; 2 int a = Integer.valueOf(1); 3 int b = (int)Integer.valueOf(1);4
- declare
Integer x
; error → cannot implicit boxint 1
toInteger 1
during assignment - declare
Integer y
; error → cannot explicit boxint 1
toInteger 1
during assignment - declare
int a
; callvalueOf
onInteger
with arguments of (int 1
) →Integer 1
; error → cannot implicit unboxInteger 1
toint 1
during assignment - declare
int a
; callvalueOf
onInteger
with arguments of (int 1
) →Integer 1
; error → cannot explicit unboxInteger 1
toint 1
during 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; 1 def x = 1; 2 float f = x + 2.0F; 3
- declare
double d
; promoteint 2
anddouble 2.0 @0
: resultdouble
; implicit castint 2
todouble 2.0 @1
→double 2.0 @1
; adddouble 2.0 @1
anddouble 2.0 @0
→double 4.0
; storedouble 4.0
tod
- declare
def x
; implicit castint 1
todef
→def
; storedef
tox
; - declare
float f
; load fromx
→def
; implicit castdef
toint 1
→int 1
; promoteint 1
andfloat 2.0
: resultfloat
; implicit castint 1
tofloat 1.0
→float
1.0; add
float 1.0and
float 2.0→
float 3.0; store
float 3.0to
f; (note this example illustrates promotion done at run-time as promotion done at compile-time would have resolved to a
def` 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 | @ | @ | @ | - | - | - | - | - | - | - | - | @ | @ | @ | @ | @ | @ | @ | @ | @ |