The ternary that unboxes
A hard Java puzzle in the null handling family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 5. Play this one as a puzzle without the answer.
What is wrong
When one operand of ?: is an int and the other an Integer, the result type is int, so table.get(code) is unboxed. A missing code returns null and the unboxing throws NullPointerException, even though the method's return type is Integer.
The fix
How to avoid it next time
Keep both branches of a ternary the same wrapper type, or avoid ternaries with nullable boxed values.
Want the background? Read Autoboxing and wrapper types in the Java concepts library.
About null handling
NullPointerException is still the most common production exception. Chained calls, auto-unboxing, maps that return null for missing keys and Optional used the wrong way all hide a null until the worst moment.
In code review: Trace each dereference back to where the value comes from and decide whether it can be null. Be wary of Optional.get, getOrDefault on null values and unboxing of Integer fields.
More puzzles in this family
Frequently asked questions
What is the bug in "The ternary that unboxes"?
When one operand of ?: is an int and the other an Integer, the result type is int, so table.get(code) is unboxed. A missing code returns null and the unboxing throws NullPointerException, even though the method's return type is Integer. The faulty line is line 5: return member ? table.get(code) : 0;
How do I fix it?
Replace it with: return member ? table.get(code) : Integer.valueOf(0);. Keep both branches of a ternary the same wrapper type, or avoid ternaries with nullable boxed values.
How do I catch null handling in code review?
Trace each dereference back to where the value comes from and decide whether it can be null. Be wary of Optional.get, getOrDefault on null values and unboxing of Integer fields.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.