What is the difference between a widening and a narrowing cast in Java, and which one does the compiler perform for you?
A widening conversion moves a value into a type that can hold every value of the original type, so no information is lost. The compiler performs these implicitly: byte to short to int to long to float to double, plus char to int and above, and int to float or double. Widening is always safe, which is exactly why the language allows it without a cast — and why a long assigned to an int requires an explicit cast, since the int cannot hold every long.
A narrowing conversion goes the other way and can lose information, so it requires an explicit cast. Narrowing from a floating-point type to an integer truncates toward zero, dropping the fractional part. Narrowing from a wider integer to a narrower one discards the high bits, keeping only the low-order bits, which is modulo arithmetic rather than saturation.
public class Main {
public static void main(String[] args) {
int small = 42;
long wide = small; // widening: implicit and always safe
double precise = small; // widening: int -> double
System.out.println("int -> long : " + wide);
System.out.println("int -> double : " + precise);
double notWhole = 9.99;
int truncated = (int) notWhole; // narrowing: fraction dropped
System.out.println("9.99 -> int : " + truncated);
char letter = 'A';
int code = letter; // widening: char -> int
System.out.println("'A' -> int : " + code);
int overflow = 300;
byte narrowed = (byte) overflow; // keeps the low 8 bits -> 44
System.out.println("300 -> byte : " + narrowed);
}
}The last line is the one to dwell on. Casting 300 to a byte does not clamp to 127; it keeps the low eight bits, so the result is 44. That is the same behaviour as integer overflow, and it is why a careless narrowing cast in a protocol parser can turn a length field into a small, plausible-looking number. Wherever a narrowing cast might actually lose data, prefer a method that either validates the range for you or throws instead of silently truncating.