IT234 Object Oriented Programming With Java

Object Oriented Programming With JavaUnit 1311 min read

Type Conversion & Casting: Rules, Methods & Pitfalls

Unit 13 of Object Oriented Programming With Java covers implicit/explicit type conversion, casting between primitives and objects, autoboxing/unboxing, and common pitfalls like data loss or compilation errors—with real-world examples from Nepalese apps like eSewa and Kathmandu traffic routing.

TAKEAWAYS:

  • Understand implicit (widening) vs. explicit (narrowing) casting and when each is used in Java.
  • Learn autoboxing/unboxing rules for converting between primitives and wrapper classes (e.g., int ↔ Integer).
  • Master type conversion in arithmetic operations and how it affects precision (e.g., double vs. int).
  • Identify common pitfalls like integer overflow, floating-point truncation, and incompatible object references.
  • Apply casting to real-world scenarios (e.g., converting eSewa transaction amounts or Daraz order status codes).
  • Write safe conversion methods using instanceof and Class.cast() to avoid runtime errors.

1. Introduction to Type Conversion

Type conversion (or type casting) is the process of converting one data type into another. Java supports two types:

  • Implicit (Widening) Conversion: Automatic conversion by Java (no data loss).
  • Explicit (Narrowing) Conversion: Manual conversion (may cause data loss).

Why is Type Conversion Needed?

  • Compatibility: Operations between incompatible types (e.g., int + double).
  • Precision Handling: Converting float to double for higher precision.
  • Memory Efficiency: Storing large numbers in smaller types (e.g., long → int).
  • Object-Oriented Casting: Converting superclass references to subclass objects (e.g., Object → String).

2. Implicit (Widening) Conversion

Java automatically converts smaller types to larger types to prevent data loss. Example: int → long → float → double.

int a = 10;
long b = a; // Implicit conversion (int → long)
System.out.println(b); // Output: 10

Widening Rules:

From To Example
byte short, int, long, float, double byte b = 5; int i = b;
short int, long, float, double short s = 10; long l = s;
char int, long, float, double char c = 'A'; int num = c; (ASCII value)
int long, float, double int x = 20; double d = x;
long float, double long y = 100; float f = y;
float double float f = 3.14f; double d = f;

Visual: Widening Conversion Hierarchy

graph LR
    byte --> short
    short --> int
    int --> long
    long --> float
    float --> double
    char --> int

3. Explicit (Narrowing) Conversion

Explicit conversion is required when converting from a larger type to a smaller type (risk of data loss). Syntax: (targetType) value

Example: Narrowing with Data Loss

double d = 99.99;
int i = (int) d; // Explicit conversion (double → int)
System.out.println(i); // Output: 99 (fractional part lost)
-10-9-8-7-6-5-4-3-2-1012345678910double (3.7)int (truncated)
Data loss when casting `double` (3.7) to `int` (3)

Common Pitfalls:

  1. Integer Overflow:
    int x = 2_000_000_000;
    byte b = (byte) x; // Overflow! Result: -72 (due to 2's complement)
    
  2. Floating-Point Truncation:
    double pi = 3.14159;
    float f = (float) pi; // Precision loss (3.1415900000000001 → 3.14159)
    
  3. Negative Values:
    long big = -1000;
    short s = (short) big; // Correct, but may overflow for larger values
    

4. Type Conversion in Arithmetic Operations

Java promotes operands to the larger type before performing arithmetic.

Example: Mixed-Type Arithmetic

int a = 5;
double b = 3.2;
double result = a + b; // a is promoted to double
System.out.println(result); // Output: 8.2
1052TOP
Operator precedence in promotion (e.g., `10 + 5 * 2` → `5 * 2` first, then `10 + 10` → `int` → `int`)

Operator Precedence in Promotion

  1. If one operand is double, the other is promoted to double.
  2. Else, if one operand is float, the other is promoted to float.
  3. Else, if one operand is long, the other is promoted to long.
  4. Else, both are promoted to int.

Visual: Promotion Table

Operand Types Result Type
byte + int int
short + long long
float + int float
double + any double

5. Autoboxing and Unboxing

Java automatically converts between primitives and wrapper classes (e.g., int ↔ Integer).

Autoboxing (Primitive → Wrapper)

int num = 10;
Integer obj = num; // Autoboxing (int → Integer)

Unboxing (Wrapper → Primitive)

Integer numObj = 20;
int primitive = numObj; // Unboxing (Integer → int)

Pitfalls of Autoboxing

  1. Performance Overhead: Autoboxing creates objects, which is slower than primitives.
  2. NullPointerException:
    Integer x = null;
    int y = x; // Throws NullPointerException
    

Visual: Autoboxing/Unboxing Flow

flowchart TD
    A["Primitive (int)"] -->|"Autoboxing"| B["Wrapper (Integer)"]
    B -->|"Unboxing"| A
    C["Wrapper (null)"] -->|"Unboxing"| D[(Error: NullPointerException)]

6. Type Casting with Objects (Downcasting/Upcasting)

In object-oriented programming, casting refers to converting between superclass and subclass references.

Upcasting (Subclass → Superclass)

class Animal {}
class Dog extends Animal {}

Dog dog = new Dog();
Animal animal = dog; // Upcasting (implicit, safe)

Downcasting (Superclass → Subclass)

Animal animal = new Dog();
Dog dog = (Dog) animal; // Downcasting (explicit, may throw ClassCastException)

Safe Downcasting with instanceof

if (animal instanceof Dog) {
    Dog dog = (Dog) animal; // Safe downcast
} else {
    System.out.println("Not a Dog!");
}

Visual: Upcasting vs. Downcasting

classDiagram
    class Animal
    class Dog
    Dog -->|extends| Animal
    note for Dog "Upcasting: Dog → Animal (safe)\nDowncasting: Animal → Dog (requires instanceof)"

7. Real-World Applications in Nepal

1. eSewa Transaction Amounts

  • Problem: eSewa stores transaction amounts as double (for decimals) but displays them as int (for rupees).
  • Solution: Explicit casting to truncate paise:
    double amount = 599.99;
    int rupees = (int) amount; // Output: 599 (paise ignored)
    

2. Daraz Order Status Codes

  • Problem: Daraz uses byte for order status (0=pending, 1=shipped, 2=delivered).
  • Solution: Widening to int for calculations:
    byte status = 1;
    int statusCode = status; // Implicit widening (byte → int)
    

3. Kathmandu Traffic Route Optimization

  • Problem: Traffic signals use short for light duration (0-60 seconds), but sensors report int values.
  • Solution: Narrowing with bounds checking:
    int sensorTime = 75;
    short lightDuration = (short) Math.min(sensorTime, 60); // Clamp to 60
    

4. Ncell Bill Calculation

  • Problem: Ncell bills use float for call charges but stores totals as double for precision.
  • Solution: Autoboxing for database storage:
    float callCharge = 125.50f;
    Double total = callCharge; // Autoboxing (float → Float → Double)
    

8. Worked Example: Safe Type Conversion

Problem: Write a method to convert a String to int safely (handle invalid inputs).

Solution:

public class SafeConversion {
    public static int stringToInt(String numStr) {
        try {
            return Integer.parseInt(numStr); // Throws NumberFormatException if invalid
        } catch (NumberFormatException e) {
            System.out.println("Invalid number format!");
            return 0; // Default value
        }
    }

    public static void main(String[] args) {
        String input1 = "123";
        String input2 = "abc";
        System.out.println(stringToInt(input1)); // Output: 123
        System.out.println(stringToInt(input2)); // Output: 0 (with error message)
    }
}

Trace Table:

Step Input Action Output
1 "123" Integer.parseInt() 123 (success)
2 "abc" Throws NumberFormatException Catches → returns 0

9. Common Exam Questions and Answers

Q1: Define type casting. Give an example.

Answer: Type casting is the process of converting one data type into another. It can be:

  • Implicit (widening): Automatic (e.g., int → double).
  • Explicit (narrowing): Manual (e.g., double → int).

Example:

double salary = 50000.50;
int monthlySalary = (int) salary; // Explicit casting (truncates decimals)

Q2: Why is explicit casting needed for double to int?

Answer: Explicit casting is required because:

  1. Data Loss: double has higher precision (64-bit) than int (32-bit). Converting double to int truncates the fractional part.
  2. Compiler Rule: Java does not allow implicit narrowing conversions to avoid unexpected behavior.

Q3: Write a program to demonstrate autoboxing and unboxing.

Answer:

public class AutoboxingDemo {
    public static void main(String[] args) {
        // Autoboxing (int → Integer)
        int num = 100;
        Integer obj = num;
        System.out.println("Autoboxing: " + obj);

        // Unboxing (Integer → int)
        int primitive = obj;
        System.out.println("Unboxing: " + primitive);
    }
}

Output:

Autoboxing: 100
Unboxing: 100

10. Exam Tip

  1. Watch for Data Loss: Always check if narrowing conversion is safe (e.g., long → byte may overflow).
  2. Use instanceof for Downcasting: Avoid ClassCastException by verifying types before casting.
  3. Autoboxing Pitfalls: Remember that null cannot be unboxed (throws NullPointerException).
  4. Arithmetic Promotion: Know the promotion rules for mixed-type operations (e.g., int + double → double).
  5. Real-World Scenarios: Relate casting to Nepalese apps (e.g., eSewa amounts, Daraz status codes).
  6. Exception Handling: Use try-catch for unsafe conversions (e.g., String → int).

11. Summary Table

Concept Example Key Point
Implicit Conversion int x = 5; long y = x; No data loss, automatic.
Explicit Conversion double d = 9.99; int i = (int)d; May lose data, manual.
Autoboxing int a = 10; Integer b = a; Primitives → wrappers automatically.
Unboxing Integer x = 20; int y = x; Wrappers → primitives automatically.
Upcasting Dog d = new Dog(); Animal a = d; Subclass → superclass (safe).
Downcasting Animal a = new Dog(); Dog d = (Dog)a; Superclass → subclass (requires instanceof).

12. Practice Questions

  1. What will be the output of the following code?

    float f = 3.14f;
    int i = (int) f;
    System.out.println(i);
    

    Answer: 3 (fractional part truncated).

  2. Why does the following code throw a ClassCastException?

    Object obj = "Hello";
    Integer num = (Integer) obj;
    

    Answer: "Hello" is a String, not an Integer. Use instanceof to check types.

  3. Convert the following String to double safely:

    String price = "19.99";
    

    Solution:

    try {
        double d = Double.parseDouble(price);
    } catch (NumberFormatException e) {
        System.out.println("Invalid price format!");
    }
    

Based on the TU BITM syllabus for Object Oriented Programming With Java (IT234), unit 13.

Discussion

Loading…