What is autoboxing and unboxing, and what pitfalls come with it?
8 minintermediateautoboxingwrapper-classespitfalls
Quick Answer
Autoboxing automatically wraps a primitive into its wrapper class (int -> Integer); unboxing extracts the primitive back out. Pitfalls: NullPointerException when unboxing a null wrapper, unexpected object identity when comparing boxed values with == (only cached -128..127 are guaranteed identical), and performance overhead from extra allocations in loops.
Detailed Answer
Autoboxing is the compiler automatically converting a primitive to its wrapper object (int → Integer); unboxing is the reverse. This lets primitives be used where an Object/generic type is required (e.g., in a List<Integer>).
List<Integer> nums = new ArrayList<>();
nums.add(5); // autoboxed: int -> Integer
int first = nums.get(0); // unboxed: Integer -> int
Common pitfalls:
- NPE on unboxing null:
Integer count = null;
int x = count; // throws NullPointerException
- Identity vs equality with
==: the JVM caches boxedIntegervalues in[-128, 127](the "Integer cache"), so==can appear to work for small numbers but breaks outside that range:
Integer a = 100, b = 100;
Integer c = 200, d = 200;
a == b; // true (cached)
c == d; // false (different objects!)
Always use .equals() (or Objects.equals) to compare wrapper values.
- Performance: boxing/unboxing in tight loops (e.g., a
Map<Integer, Integer>counter) allocates extra objects and adds overhead versus primitive arrays or specialized collections. - Overload ambiguity: mixing boxed and primitive overloads can pick a surprising method at compile time.