liveBook · Manning

Narrowing conversion

As explained in 100 Java Mistakes and How to Avoid Them

A narrowing conversion converts a value to a type with a smaller representable range or less general numeric domain, potentially discarding information.

A narrowing conversion changes a value to a type with a smaller range or less general numeric domain. Java may discard higher bits, overflow, lose precision, or produce a result that looks valid but is wrong. The risk is especially easy to miss in explicit casts and compound assignments. section 4.16 section 4.7

A cast can corrupt a file length

Passing `(int) file.length()` to a method discards information when the file exceeds the `int` range. A 5,000,000,000-byte file becomes 705,032,704 after narrowing, potentially causing an exception, incorrect behavior, or silent data corruption. section 4.7

processFileLength((int) file.length());

Inspect the explicit narrowing cast in a focused file-processing call. section 4.7

Compound assignment hides another narrowing conversion. `x *= y` behaves like `x = (type_of_x)(x * y)`, so arithmetic is performed before the result is converted back. A `char` can change from `'a'` to `'t'`, while adding 256 to a negative `byte` can restore the original negative value instead of producing an unsigned result. section 4.9

Reduce the risk with targeted checks and types:

  • Before an explicit cast, establish that the value always fits the target type and document why the cast is safe. section 4.7
  • Use `Math.toIntExact()` when an out-of-range `long` should fail with `ArithmeticException` rather than silently lose information. section 4.7
  • Prefer `int` or `long` over `byte` and `short` when possible, and use `long` for quantities such as file sizes or millisecond durations. section 4.16 section 4.9
  • Do not rely entirely on static analysis: IntelliJ inspections can flag harmless casts or miss complex compound-assignment cases. section 4.7 section 4.9
byte b = getByte();
if (b < 0) {
  b += 256;     #1
}

Trace how `b += 256` widens the byte for arithmetic and then narrows it back, undoing the intended conversion. section 4.9

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Works through overflow, bit loss, widening order, and analyzer limits, then stops short of a general numeric-conversion taxonomy.
Examples
Uses file lengths, character multiplication, negative bytes, and unsigned right shifts as concrete failure cases.
What you can do after
Diagnose unsafe casts and compound assignments, then replace them with range checks, exact conversion, or wider types.
How it connects
Connects narrowing conversion to compound assignment, numeric overflow, primitive types, unsigned conversion, and static analysis.

Also explained in

Compare how 3 books explain narrowing conversion →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.