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 (intInteger); 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:

  1. NPE on unboxing null:
Integer count = null;
int x = count; // throws NullPointerException
  1. Identity vs equality with ==: the JVM caches boxed Integer values 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.

  1. 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.
  2. Overload ambiguity: mixing boxed and primitive overloads can pick a surprising method at compile time.

Related Resources