Java Type Casting
Convert between primitive types in Java using implicit widening conversion and explicit narrowing casts, and avoid common pitfalls.
Type casting is converting a value from one type to another. In Java that comes in two flavours: widening conversions, which happen automatically and never lose information, and narrowing conversions, which require an explicit cast and can lose data.
Widening (implicit) conversion
A widening conversion moves a value into a larger type. The compiler does it for free — no syntax needed:
int i = 100;
long l = i; // int → long (widening)
double d = l; // long → double (widening)
System.out.println(i); // 100
System.out.println(l); // 100
System.out.println(d); // 100.0The standard widening order is:
byte → short → int → long → float → double
char ↗(char widens to int and onwards, but not to short or byte.)
Widening never loses range — a long always fits in a double's range, even if double cannot represent every long value exactly. Watch for that exact-representation gap at extreme values.
Narrowing (explicit) cast
A narrowing conversion moves a value into a smaller type. Java refuses to do this implicitly because data can be lost. You must spell it out with (targetType):
double d = 9.99;
int i = (int) d; // explicit narrowing cast
System.out.println(i); // 9 — the fractional part is droppedThe cast truncates toward zero — it does not round.
For integers, a cast keeps only the low-order bits:
int big = 130;
byte b = (byte) big;
System.out.println(b); // -126 — overflow wraps aroundbyte is 8 bits, range -128…127. The bits of 130 (10000010) interpret as -126 in two's complement.
A common cast: integer division to a real number
Pure integer arithmetic uses integer division — 5 / 2 == 2, not 2.5. To get a real result, cast at least one operand before the division:
int total = 5;
int count = 2;
double avgWrong = total / count; // 2.0 — division is still integer
double avgRight = (double) total / count; // 2.5 — total widened firstThis is the single most common reason to reach for a cast.
Reference casts
The (Type) syntax also works on objects — though there it's a runtime check, not a conversion. Casting a reference is essentially saying "trust me, this object is of type X":
Object o = "Hello";
String s = (String) o; // OK at runtime
System.out.println(s.length()); // 5
Object n = Integer.valueOf(7);
String bad = (String) n; // throws ClassCastException at runtimePattern matching for instanceof (modern Java) lets you do the check and the cast in one step. Reference casts are covered properly in OOP and Polymorphism.
A working example
When the compiler "helps" — and when it doesn't
A subtle case to watch for: arithmetic on byte, short, or char is automatically promoted to int before the operation. The result is an int:
byte a = 10;
byte b = 20;
// byte sum = a + b; // compile error: result is int
byte sum = (byte) (a + b); // explicit cast neededThis catches everyone the first time. Either store the result in int, or cast back.
Rules of thumb
- Widen freely — no cast needed, no loss.
- Narrow with a cast and a check — make sure the value really fits.
- For real-number division of integers, cast one operand to
double. - For monetary calculations, don't use
doubleat all — useBigDecimalto avoid binary floating-point rounding errors.
What's next
Java Operators — the full overview of every operator the language ships with.
Practice
Which conversions require an explicit cast?