Autoboxing & unboxing in Java
Automatic conversion, NullPointerException when unboxing null.
int count = stock; One innocent line, and your program crashes with NullPointerException. There isn't even a method call! Or is there?Automatic wrapping
Since Java 5, autoboxing wraps a primitive into its wrapper when an object is needed, and unboxing extracts the primitive when a primitive is needed. The compiler inserts the calls for you.
Integer x = 5; // Integer.valueOf(5)
int y = x; // x.intValue()Collections hold objects
A List<Integer> holds Integer objects, never raw ints. Boxing makes that painless: you add ints and read ints, and Java converts in between.
List<Integer> nums = new ArrayList<>();
nums.add(3); // boxed
int first = nums.get(0); // unboxedYour turn
What does this print?
List<Integer> nums = new ArrayList<>();
nums.add(10);
nums.add(5);
int diff = nums.get(0) - nums.get(1);
System.out.println(diff);5105Compile error
Show the answer
add boxes 10 and 5 into Integers. get returns Integer objects, which are unboxed for the subtraction: 10 - 5 = 5.
Your turn
bonus is null. What happens?
Integer bonus = null;
int total = 100 + bonus;
System.out.println(total);100Throws NullPointerExceptionCompile error
Show the answer
Unboxing secretly calls bonus.intValue(), and there's no object to call it on. NullPointerException. null does not become 0.
remove(1): index or value?
List has remove(int index) and remove(Object value). The argument 1 is an int, which matches remove(int) exactly, with no boxing, so it removes index 1. To remove the value, write list.remove(Integer.valueOf(1)).
List<Integer> list =
new ArrayList<>(List.of(10, 20, 30));
list.remove(1);
// [10, 30]: index 1 removedBoxing isn't free
Long total = 0L;
for (long i = 0; i < n; i++) {
total += i;
}Each += unboxes total, adds, then boxes the result into a new Long object, nearly every iteration.
long total = 0L;
for (long i = 0; i < n; i++) {
total += i;
}Plain primitive arithmetic: no objects created at all.
In real projects
Unboxing NPEs are a top production bug: a database column or JSON field is missing, a mapper leaves an Integer null, and int qty = order.getQty(); crashes far away from the real cause.
Key takeaways
- Integer x = 5; → autoboxing
- int y = x; → unboxing (calls x.intValue())
- Unboxing null → NullPointerException
- Collections hold Integer, never int
Autoboxing arrived in Java 5 (2004), together with generics, enums, varargs and the for-each loop: one of the biggest updates in Java's history.
Practice questions
What does this print?
List<Integer> nums = new ArrayList<>();
nums.add(3);
nums.add(4);
int sum = nums.get(0) + nums.get(1);
System.out.println(sum);- 7
- 34
- Compile error
- Throws ClassCastException
Check your answer
7. add(3) boxes 3 into an Integer. get returns Integer objects, which are unboxed for +, giving 7.
What does this print?
Integer stock = null;
int count = stock;
System.out.println(count);- 0
- null
- Throws NullPointerException
- Compile error
Check your answer
Throws NullPointerException. int count = stock unboxes by calling stock.intValue(). stock is null, so the JVM throws NullPointerException.