All topics
library
beginner

Type Casting: Widening & Narrowing

Know when Java casts automatically (widening), when you must cast explicitly (narrowing), and the data loss risks.

Going to a bigger type is automatic. Going to a smaller one you must ask for, and may lose data.

Widening = pouring a small glass of water into a big glass (always fits). Narrowing = pouring a big glass into a small one (overflow/loss).

Key Concepts

1
    widening  (implicit)   byte -> short -> int -> long -> float -> double
                           char -> int
    narrowing (explicit)   the other direction, with a cast
2
    int i = 42;
    long l = i;              // widening, automatic
    int back = (int) l;       // narrowing, cast required
3
Narrowing truncates, it does not round.
    (int) 3.99               // 3
    (byte) 256               // 0   -- the low 8 bits are all zero
    (byte) 130               // -126 -- wraps into signed range
4
And one widening conversion loses data too, which surprises people:
5
    int big = 123456789;
    float f = big;           // widening, no cast needed
    (int) f                   // 123456792 -- not what went in
6
A float has 32 bits but only 24 for the significand, so an int larger than about 16.7 million cannot be represented exactly. long to float and long to double have the same problem.
floatintlongdouble
7
Reference casts are a different thing. Upcasting is always safe:
8
    Dog d = new Dog();
    Animal a = d;            // implicit, always valid
9
Downcasting is checked at runtime:
10
    Animal a = new Cat();
    Dog d = (Dog) a;         // ClassCastException
11
So test first.
    if (a instanceof Dog) {
      Dog d = (Dog) a;
      d.fetch();
    }
12
Since Java 16 the test binds the variable and the cast disappears:
13
    if (a instanceof Dog d) {
      d.fetch();
    }
14
Which is shorter and removes the chance of casting to the wrong type by hand — the two type names can no longer disagree.
15
What the interviewer is probing.1. "Is a widening conversion always lossless?" Probing: whether you know the exception to the rule. Stalls: "Yes, that is why it is implicit." Moves up: int to float is widening and can lose precision, because float has only 24 bits of significand — the same applies to long to float or double.
16
2. "What does (byte) 130 give you?" Probing: truncation and sign. Stalls: "130." Moves up: -126 — the value wraps into the signed byte range, because narrowing keeps the low bits.
17
3. "(int) 3.99 — does it round?" Probing: truncation versus rounding. Stalls: "4." *Moves up:* 3 — a cast truncates toward zero; Math.round is what rounds.
18
4. "How do you downcast safely?" Probing: whether you reach for instanceof and the modern form. Stalls: "Just cast it." Moves up: test with instanceof first, and since Java 16 bind in the same step: if (o instanceof Dog d), which removes the chance of the two type names disagreeing.