liveBook · Manning

Boxed primitive

As explained in 100 Java Mistakes and How to Avoid Them

A boxed primitive type is a reference type that wraps a Java primitive value, such as Integer wrapping int, and can represent null.

A boxed primitive is a reference type such as Integer, Double, or Boolean that holds a primitive value and can also be null. That extra null state and Java’s implicit boxing and unboxing make wrappers convenient but risky: they add overhead and can turn an apparently ordinary expression into a NullPointerException. Prefer primitive types unless a reference type is required, such as for a generic type parameter. section 2.15 section 5.1.1

Unboxing is especially hazardous in conditional expressions. When one branch is a wrapper and the corresponding other branch is primitive, the primitive type wins while Java determines the conditional expression’s type. Java then unboxes the wrapper before evaluating the result, and boxes the final value again if the surrounding target is a wrapper. A null wrapper therefore fails before it can be returned as null. section 2.6.1

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

Although this looks like it returns value unchanged when condition is true, the conditional expression is a primitive double expression; a null value is unboxed and throws NullPointerException. section 2.6.1

Avoid wrapper-related failures with a few direct rules:

  • Use an if statement rather than a conditional expression when branches have different types, particularly a primitive and its wrapper. section 2.6.1
  • Avoid nested conditional expressions that mix null, primitive values, and wrapper values; their grouping can change the inferred result type and whether null is unboxed. section 2.6.2
  • Do not encode a third Boolean state with null. Declare an enum with named outcomes when true, false, and another action such as cancel must be distinguished. section 5.1.1
  • Compare wrapper contents with equals(), not ==. Reference equality may appear to work for autoboxed cached values and then fail for other values or construction paths. section 7.1 section 7.15

Nested conditionals can unbox null

A return expression shaped like input > 20 ? 2 : input > 10 ? 1 : null appears to produce Integer values 2, 1, or null. For input values of 10 or less, however, its type calculation can produce int and unbox null. Reordering the conditions can yield an Integer result instead, but relying on that distinction is fragile. Write explicit if statements rather than depending on conditional-expression conversion rules. section 2.6.2

Static analysis can help, but it is not decisive. IntelliJ IDEA and PVS-Studio report the possible null unboxing in the nested conditional example. SonarLint instead objects to the nesting; extracting an inner expression can remove that warning even though the unboxing problem remains. section 2.6.2

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains conditional-expression type conversion and autounboxing consequences, while recommending if statements instead of memorizing all rules.
Examples
Uses Double value-or-zero conditionals, nested Integer mapping, a three-outcome confirmation, and cached Integer comparisons.
What it assumes
Assumes familiarity with Java primitives, reference types, conditional expressions, and method calls; explains wrapper conversion behavior through examples.
What you can do after
Diagnose/debug null-unboxing and unreliable wrapper equality, then replace fragile expressions with primitives, if statements, enums, or equals().
How it connects
Connects primitive wrappers with conditional expressions, autoboxing, null handling, enums, and equals().

Also explained in

Compare how 2 books explain boxed primitive →

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.