In Java, casting is the process of converting a variable from one data type to another. There are two main types of casting: primitive type casting and reference type casting. Each has specific rules and use cases.
1. Primitive Type Casting
This involves converting one primitive data type into another. There are two subtypes:
a) Widening Casting (Implicit Casting)
- Automatically done by Java when converting a smaller data type to a larger one.
- No data loss occurs.
- Example:
int num = 100; double doubleNum = num; // Implicit casting System.out.println(doubleNum); // Output: 100.0
- Order of Widening:
byte → short → int → long → float → double
b) Narrowing Casting (Explicit Casting)
- Must be done manually when converting a larger data type to a smaller one.
- May result in data loss or precision errors.
- Example:
double doubleNum = 100.99; int num = (int) doubleNum; // Explicit casting System.out.println(num); // Output: 100
2. Reference Type Casting
This involves converting objects or classes. It is applicable only to objects that share an inheritance relationship. Reference casting has two subtypes:
a) Upcasting
- Converting a subclass object into a superclass reference.
- Done implicitly.
- Example:
class Animal { void sound() { System.out.println("Animal makes sound"); } } class Dog extends Animal { void sound() { System.out.println("Dog barks"); } } public class Main { public static void main(String[] args) { Animal a = new Dog(); // Upcasting a.sound(); // Output: Dog barks } }
b) Downcasting
- Converting a superclass reference back into a subclass object.
- Must be done explicitly using a cast.
- Can throw a
ClassCastException
if not handled properly. - Example:
Animal a = new Dog(); // Upcasting Dog d = (Dog) a; // Downcasting d.sound(); // Output: Dog barks
3. Casting Between Non-Primitive Types
This is limited to classes/interfaces that are compatible:
- Casting Between Interfaces: Possible when classes implement multiple interfaces.
- Example:
interface A {} interface B {} class C implements A, B {} public class Main { public static void main(String[] args) { A objA = new C(); B objB = (B) objA; // Interface casting } }
Key Points to Remember
- Primitive Casting: Always follow the widening or narrowing rules.
- Reference Casting: Only possible with objects having an inheritance relationship.
- Always check for compatibility using the
instanceof
operator before downcasting.if (a instanceof Dog) { Dog d = (Dog) a; }