📦 Variables & Types · Beginner

Autoboxing & unboxing in Java

Automatic conversion, NullPointerException when unboxing null.

🧩 The mysteryint 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);  // unboxed
🔮 Predict it

Your 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);
  1. 5
  2. 105
  3. Compile error
Show the answer

add boxes 10 and 5 into Integers. get returns Integer objects, which are unboxed for the subtraction: 10 - 5 = 5.

🔮 Predict it

Your turn

bonus is null. What happens?

Integer bonus = null;
int total = 100 + bonus;
System.out.println(total);
  1. 100
  2. Throws NullPointerException
  3. Compile error
Show the answer

Unboxing secretly calls bonus.intValue(), and there's no object to call it on. NullPointerException. null does not become 0.

⚠️ The trap

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 removed

Boxing isn't free

✗ Slow
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.

✓ Fast
long total = 0L;
for (long i = 0; i < n; i++) {
    total += i;
}

Plain primitive arithmetic: no objects created at all.

💼 In the real world

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

  1. Integer x = 5; → autoboxing
  2. int y = x; → unboxing (calls x.intValue())
  3. Unboxing null → NullPointerException
  4. Collections hold Integer, never int
🤯 Did you know?

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);
  1. 7
  2. 34
  3. Compile error
  4. 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);
  1. 0
  2. null
  3. Throws NullPointerException
  4. Compile error
Check your answer

Throws NullPointerException. int count = stock unboxes by calling stock.intValue(). stock is null, so the JVM throws NullPointerException.

Next: two Integers holding 127 are ==. Two Integers holding 128 are not. No, really. Prepare for the Integer cache.