library
beginnerType 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 cast2
int i = 42;
long l = i; // widening, automatic
int back = (int) l; // narrowing, cast required3
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 range4
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 in6
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 valid9
Downcasting is checked at runtime:
10
Animal a = new Cat();
Dog d = (Dog) a; // ClassCastException11
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.