Saturday, 13 August 2011

Type casting - Implicit and explicit

The basics
Whenever you create a class in java, you create a new data type. You can create instances of these classes  which are referred to as objects. To work with the objects you would need a variable through which you refer the objects, these are called as the reference variable and the object that the variable refers to is called the referred object.

Creating a reference variable with the java statement
         Employee employee;  (In general ReferenceType reference)
will not create an object of Employee instead it will just mean that we have created a reference variable for an object of type Employee.
This reference can hold the value of null or an object of ReferenceType  or any object whose type is subclass of ReferenceType.The reference type could be a interface/abstract class/class. The type of the reference determines how the referenced object i.e the object that is the value of the reference can be used,(you can use the behavior of the referenced object or its superclasses if any).  However, the object type of the referred object determines the behavior of the variable at runtime (FYI, polymorphism).

So what is casting?
Type casting happens when one data type is converted to another data type or it simply means treating a variable of one type as though its another type. There are 2 ways a casting can happen 
  1. Upcasting - also called widening conversions. Its easy to convert a subclass to the superclass, reason a subclass object is also a superclass object. Ex casting a SavingAccount object to an Account class variable is automatic.
  2. Downcasting - also called narrowing conversions, this requires an explicit cast and also that the object that is casted is a legitimate instance of the class you are casting too. When you code for explicit casting you tell the compiler, that you understand/take responsibility that the reference variable will hold an object of the reference type or its subclass. The JVM will then check for the correctness of this at runtime.
You can also cast an object to an interface provided that the object's class or any one of it superclass   implement the interface .

Casting can be applied to primitives as well. The primitives are placed in the following hierarchy/order,

             byte--- short---int---long---float---double.  \
Upcasting happens automatically when you go from left to right, but if you go from right to left explicit casting is required. Ex: Casting a short to a byte is possible, however if the value of the variable of type short exceeds the permissible value that can be handled by byte, then this conversion can lead to an overflow condition at runtime. Remember java does not inform us with exceptions, about overflow or underflow conditions, so care should be taken to understand the overflow and underflow behavior for such numerical conversions and computations.

When is ClassCastException thrown?
ClassCastException is thrown when you attempt to cast an object to a class of which it is not an instance.
Ex You cannot assign an Account object to a SavingAccount variable.   Although you could get away with the compile time error or Type mismatch error by explicit casting; it would fail at runtime with ClassCastException. A Type mismatch error also occurs when you try to reference a object of a different hierarchy. (Ex. trying to assign an employee object to an Account class variable)

You can deal with incorrect casting in 2 ways
  1. Catching the ClassCastException with the try-catch block
  2. Before casting use to instanceof operator to check if the object being casted is an legitimate instance of the reference type else be sure to deal with it either through the else block or the exception being generated.
You could also get a ClassCastException when two different class loaders load the same class because they are treated as two different classes.

What happens when you assign a reference variable with value null to a specific type. Say,   Account acc = (Account) acc1;  where acc1 is null. Casting has nothing to do with the value of the referenced object it just lets the compiler know that you know what you are doing (refer, Downcasting)

However, thing to note is when you have overloaded methods Example, myMethod(String s) and myMethod(Integer i) and you want to pass null as a parameter, then you need to explicitly cast so that the compiler knows which method to call, else it cribs saying the invocation is ambiguous.

No comments:

Post a Comment