liveBook · Manning

Unboxing

As explained in 100 Java Mistakes and How to Avoid Them

An unboxing conversion converts a Java wrapper object to the corresponding primitive value, and can throw NullPointerException when the object is null.

Unboxing is Java’s implicit conversion from a wrapper object such as Integer, Double, or Boolean to its primitive value. Conceptually, Java calls an instance method such as doubleValue(). That hidden call matters because unboxing null throws NullPointerException. section 2.6.1 section 5.1.1

A common trap is a conditional expression with one boxed numeric branch and one primitive branch. The primitive type can win during type selection, forcing the boxed branch to unbox; the final primitive result may then be boxed again for a boxed return type. Thus valueOrZero(true, null) throws rather than returning null. section 2.6.1

Double valueOrZero(boolean condition, Double value) { 
  return Double.valueOf( 
           condition ? value.doubleValue() : 0.0);  
}

Making the implicit conversions explicit reveals both the null-sensitive doubleValue() call and the final reboxing. section 2.6.1

Nested ternaries make the type calculation still harder to see. A seemingly valid Integer result containing 2, 1, or null can unbox null in one ordering of conditions, while a reordered version can avoid unboxing because it resolves to Integer instead. Do not infer safety from the declared return type alone. section 2.6.2

Prefer designs that make nullability and alternatives explicit:

  • Convert boxed numeric values to primitives early when null is not meaningful; this makes the non-null requirement visible. section 2.6.1
  • Replace numeric ternaries—especially nested ones or branches of different types—with if statements. section 2.6.1 section 2.6.2
  • Do not use a nullable Boolean to represent a third outcome such as Cancel; use an enum and switch so callers must handle every outcome. section 5.1.1
  • Validate API inputs with requireNonNull() when null is not accepted. section 5.1.1

Nullable Boolean at an if condition

Changing a two-outcome decision from boolean to Boolean so that null means Cancel preserves compilation at existing if call sites. When Cancel occurs, the if condition automatically unboxes null and throws NullPointerException. An enum such as YES, NO, CANCEL makes the additional state explicit and supports a switch-based decision. section 5.1.1

Static analysis can identify some unboxing hazards, but coverage differs. IntelliJ IDEA reports a possible exception from unboxing, and PVS-Studio has an automatic-unboxing warning; SonarLint may instead flag nested ternaries and miss the remaining null-unboxing risk after refactoring. section 2.6.2

Unboxing also changes which comparison operation is used. Double.equals() distinguishes boxed +0.0 and -0.0, whereas comparing a Double with primitive -0.0 unboxes the Double and yields primitive comparison behavior. This can expose signed-zero differences in collections and generated record equality. section 4.15.1

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains implicit conversion effects through expanded code and conditional-expression type outcomes, without specifying runtime internals.
Examples
Uses nullable Double ternaries, nested Integer ternaries, a nullable Boolean dialog result, and signed-zero Double comparisons.
What it assumes
Assumes familiarity with Java wrapper and primitive types while clarifying their implicit conversions in expressions.
What you can do after
Diagnose/debug with it by locating implicit primitive conversions that can unbox null and by replacing fragile control flow.
How it connects
Connects unboxing to boxing, conditional expressions, nullability, enums, static analysis, and floating-point comparison.

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.