The process of converting one data type to another is called casting. Casting is often necessary when a function returns a data of type in different form then we need to perform an operation. Under certain circumstances Type conversion can be carried out automatically, in other cases it must be "forced" manually (explicitly). For example, the read() member function of the standard input stream (System.in) returns an int. If we want to store data of type int returned by read() into a variable of char type, we need to cast it :
char k = (char)System.in.read();
The cast is performed by placing the desired type in parentheses to the left of the value to be converted. The System.in.read() function call returns an int value, which then is cast to a char value because of the (char) cast. The resulting char value is then stored in the char variable k.
The storage size of the types while casting is very important otherwise the data loss will occur. For example, suppose we cast a long to an int. A long is a 64-bit value and an int is a 32-bit value. When casting a long to an int, the compiler truncates the upper 32 bits of the long value so as to fit into the 32-bit int. If the upper 32 bits of the long contain any useful information, then data loss will occur.
In some cases, the data type of the expression is changed automatically to the variable's data type. For example, suppose that i is an integer variable declared as follows:
int i = 10;
Even though d is a variable of type double, the following assignment is valid:
double d = i; // valid, i is converted to type double
Java changes i from int to double, and then assigns it to d. This conversion does not cause any loss of information because the double data type is 64 bits wide and thus is wider than the int data type that has 32 bits. This is called a widening conversion because a narrower type is converted to a wider type, and it takes place implicitly. Here are some more examples of when widening conversions occur:
short s = 10;
int num= s;
float f = num;
double d = f;
Figure summarizes the conversion rules: A conversion occurs from a given data type to any of the data types on its right. For example, a conversion from byte to anyone of the following can take place: short, int, long,float, and double; however, a float can be converted only to a double.
On the other hand, assigning a value of type double to an int causes a compilation error:
double d = 100.5;
int i = d; // error!
Java does not allow this assignment because a double can hold a larger range of values than an int, and it could result in an inadvertent loss of data if d is larger than the largest value that can be stored in an int, or if it is smaller than the smallest value that can be stored in an into To allow this type of assignment, it is necessary for the programmer to force a conversion from double to int using a cast.
For example, a cast is used here to force a conversion of the variable d to type int and then assign it to i:
int i = (int) d; // i = 100
Note that this assignment truncates (not rounds) the fractional part so that it assigns 100 to i.
Figurealso depicts all cases when casting is needed; a cast must be used to convert a particular type to any of the types on its left. Thus, a cast is needed to convert from type float to type byte, short, int, or long:
float f = (float) 10.5; // cast a literal of type double to float
byte b = (byte) f; // cast a float to byte
short s1 = (short) f; // cast a float to short
int i = (int) f; // cast a float to int
long 1 = (long) f; // cast a float to long
A booleanvariable can be assigned only values of type boolean. Conversely, a variable of any of the other data types cannot be assigned a boolean value.
Automatic Conversion: In Java type conversions are performed automatically when the type of the expression on the right hand side of an assignment operation can be safely promoted to the type of the variable on the left hand side of the assignment. Thus we can safely assign: byte -> short -> int -> long -> float -> double.
For example :
//64 bit long integer
//32 bit long integer
The extra storage associated with the long integer, in the above example, will simply be padded with extra zeros.
Explicit Conversion (Casting): The above will not work the other way round. For example we cannot automatically convert a long to an int because the first requires more storage than the second and consequently information may be lost. To force such a conversion we must carry out an explicit conversion (assuming of course that the long integer will fit into a standard integer). This is done using a process known as a type cast :
myInteger = (int) myLongInteger
This tells the compiler that the type of myLongInteger must be temporarily changed to a int when the given assignment statement is processed. Thus, the cast only lasts for the duration of the assignment. Java type casts have the following form: (T) N where T is the name of a numeric type and N is a data item of another numeric type. The result is of type T.
Casting between classes can be broken into three different situations:
• Casting from a subclass to a superclass
• Casting from a superclass to a subclass
In the case of casting from a subclass to a superclass, we can cast either implicitly or explicitly. Implicit casting simply means auto casting; explicit casting means that we have to provide the class type in parentheses. Casting from subclass to superclass is completely reliable because subclasses contain information about their super classes.
Casting from a superclass to a subclass has to be done explicitly and is also not reliable because the compiler has no idea whether the class being cast to is a subclass of the superclass or not.
Double a = new Double (12.75);
Number b = a;
Double c = (Double) b;
Long d = a; / / results in error
In this example, data type wrapper objects are created and assigned to each other. The Double and Long sibling classes are both derived from the Number class. In the example, after the Double object a is created, it is assigned to a Number object. This is an example of implicitly casting from a subclass to a superclass. Another Double object, c, is then assigned the value of the Number object. Since, we are casting from a superclass to a subclass, an explicit casting is required. Finally, a Long object is assigned the value of a Double object. This is a casting between siblings and is not allowed in Java so results in an error.