A Long that is never equal to one
A medium Java puzzle in the boxing and generics 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 6. Play this one as a puzzle without the answer.
What is wrong
The literal 1 is boxed to an Integer, and Long.equals returns false for any argument that is not a Long. The values look the same but the types differ, so the comparison is always false.
The fix
How to avoid it next time
Use matching types in equals. Use long literals with Long, and prefer primitives for comparisons.
Want the background? Read Autoboxing and wrapper types in the Java concepts library.
About boxing and generics
Autoboxing, overload resolution and generics erasure change what a line of code means. The Integer cache, List.remove(int) versus remove(Object) and raw types all behave in ways that surprise careful readers.
In code review: Check the static types involved. When an overloaded method takes either a primitive or an object, work out which one the compiler picks.
More puzzles in this family
Frequently asked questions
What is the bug in "A Long that is never equal to one"?
The literal 1 is boxed to an Integer, and Long.equals returns false for any argument that is not a Long. The values look the same but the types differ, so the comparison is always false. The faulty line is line 6: boolean same = id.equals(expected);
How do I fix it?
Replace it with: boolean same = id.equals(1L);. Use matching types in equals. Use long literals with Long, and prefer primitives for comparisons.
How do I catch boxing and generics in code review?
Check the static types involved. When an overloaded method takes either a primitive or an object, work out which one the compiler picks.
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.