Java

Chapter 8: Type Casting in Java — Widening, Narrowing, and Data Loss

Learn type casting in Java: implicit widening, explicit narrowing casts, char and int promotion rules, common data-loss bugs, and safe habits with literals.

Author: Sushil Kumar

Java type castingwidening casting Javanarrowing cast JavaJava int to doubleJava explicit cast

Chapter 8: Type Casting in Java

This chapter is only about type casting: changing a value from one type to another safely or explicitly at your own risk. Operators and variables are already in your head from Chapters 5–7.


1. Topic title

Type casting in Java: widening, narrowing, explicit casts, and where data gets lost


2. What it means

Casting means telling Java to treat a value as a different type.

Two big ideas:

Widening (implicit): going from a smaller numeric range to a larger one. Java allows this without a cast because you usually do not lose information.

int x = 42;
double d = x; // int → double, implicit

Narrowing (explicit): going from larger to smaller or from double to int. You must write the cast. You may lose data (fractions, high bits).

double pi = 3.99;
int i = (int) pi; // i becomes 3 — fraction thrown away

3. Why it is used

Sometimes an API gives you a double but your domain wants whole units. Sometimes you read bytes from a file as int values. Sometimes legacy code returns Object and you know it is a String—casting (carefully) bridges worlds.

Casting is a tool. Sloppy casting is a bug factory.


4. Real-world example

A sensor reports double voltage 3.7. Your display firmware wants millivolts as an int. You multiply by 1000 and cast:

double volts = 3.7;
int millivolts = (int) (volts * 1000); // 3700

The cast applies to the result of the multiplication because of parentheses. Wrong parentheses order is a classic bug.


5. Java code example

public class CastingDemo {
    public static void main(String[] args) {
        int count = 100;
        long big = count;
        System.out.println("int to long widening: " + big);
 
        double avg = count / 3;
        System.out.println("int division surprise: " + avg);
 
        double avgFixed = count / 3.0;
        System.out.println("force double division: " + avgFixed);
 
        double score = 87.7;
        int roundedDown = (int) score;
        System.out.println("cast double to int truncates: " + roundedDown);
 
        char letter = 'A';
        int code = letter;
        System.out.println("char widens to int (Unicode value): " + code);
 
        int small = 130;
        byte b = (byte) small;
        System.out.println("narrow int to byte can wrap: " + b);
 
        byte b1 = 3;
        byte b2 = 4;
        int sum = b1 + b2;
        System.out.println("byte + byte promotes to int: " + sum);
    }
}

Run it and read the byte wrap line—narrowing can produce “impossible” negatives if the value does not fit.


6. Explanation of code

Widening chain (rough mental picture for whole numbers): byteshortintlong. Floating: floatdouble. charint (numeric code).

Narrowing: (targetType) value chops or reinterprets bits to fit. Out-of-range int to byte wraps—not clamped to 127.

count / 3 vs count / 3.0: first is integer division; second promotes to double division because 3.0 is a double.

byte + byte is int: arithmetic on byte/short promotes to int in Java. Assigning back to byte needs a cast—and risks overflow.


7. Common mistakes

Casting to “fix” integer division in the wrong place:

(double) (a / b) // still integer division inside parentheses first

Use (double) a / b or a / (double) b.

Silent overflow when stuffing large int into byte/short without thinking.

Casting Object to anything without instanceof checks—ClassCastException at runtime.

Assuming cast rounds to nearest—(int) truncates toward zero for positives.


8. Best practices

Prefer widening without casts; let the compiler insert safe conversions.

Narrow only at boundaries you control (user input validation, protocol parsing), not scattered through business logic.

Use Math.round, Math.floor, Math.ceil when you need real rounding rules—not raw (int)—unless truncation is exactly what you want.

Validate before narrow casts from user or network data.


9. Small practice task

Start with double temperature = 36.7. Produce:

  • an int named wholePart using a cast (expect 36),
  • a rounded integer nearest using Math.round(temperature) (returns long—store in int with a cast if you like).

Print both and explain in a comment which one you would use for a “fever yes/no at 38.0 threshold” check.


Beginner tip

If a cast “fixes” a compile error but the number looks insane at runtime, suspect overflow or wrong parentheses, not ghosts.