Boxing conversion turns a Java primitive into its corresponding wrapper object, such as double into Double. Java may perform it implicitly, effectively through calls such as Double.valueOf(); the reverse operation, unboxing, extracts a primitive through methods such as doubleValue(). These invisible conversions matter when an expression mixes wrapper and primitive numeric types. section 2.6.1
A conditional expression can unbox null
In `return condition ? value : 0.0;`, where `value` is a `Double`, the primitive `0.0` makes the conditional expression a primitive `double`. Java therefore unboxes `value` before choosing the result, then boxes the result for the `Double` return type. Calling the method with `condition` true and `value` null throws `NullPointerException`, rather than returning null. section 2.6.1
Double valueOrZero(boolean condition, Double value) {
return Double.valueOf(
condition ? value.doubleValue() : 0.0);
}
Making the conversions explicit reveals both the unboxing that can fail and the final reboxing. section 2.6.1
Treat mixed primitive-wrapper conditionals as fragile code:
- Prefer primitives where null is not meaningful; converting a wrapper early makes the non-null requirement visible. section 2.6.1
- Use an `if` statement when a boxed result is needed instead of a conditional whose branches mix primitive and wrapper types. section 2.6.1
- Avoid nested conditional expressions, especially when a branch is primitive; their type rules can introduce an unboxing of null. section 2.6.2
- Use data-flow warnings as help, not proof: IntelliJ IDEA and PVS-Studio can flag possible null unboxing, while SonarLint may miss it after a nested conditional is extracted. section 2.6.2
Autoboxing also creates object-identity traps. `Integer i1 = 100; Integer i2 = 100;` can make `i1 == i2` true because small Integer values are cached. Larger values may create separate objects, and cache behavior can vary. Compare wrapper contents with `equals()`, not `==`; Boolean and Byte caching do not make reference equality a content comparison. section 7.1
A boxed boolean can make a test meaningless
`assertNotNull(data.isEmpty())` compiles because the primitive boolean result is boxed as a `Boolean`. That object is non-null, so the assertion always passes and does not test whether the data is empty. Use `assertTrue()` or `assertFalse()` for boolean conditions. IntelliJ IDEA can report an obviously non-null boxed boolean passed to a null-check method. section 10.2
Boxing can also expose distinctions hidden by primitive comparison. Java primitive `+0.0` and `-0.0` compare equal with `==`, but boxed `Double` values treat them as different through `Double.equals()`. A `Set<Double>` can therefore retain both zero values. Normalize zero before storing it when that distinction is unwanted. section 4.15.1


