Lesson 9 / 38
Wrapper Classes & Autoboxing
Meet the object wrapper for every primitive, see how autoboxing/unboxing convert between them automatically, and learn the classic == pitfall with boxed Integers.
A wrapper for every primitive
int→Integer, double→Double, boolean→Boolean, char→Character, and so on. Wrappers are full objects: they can be null, stored in collections (which only hold objects), and carry useful statics like Integer.MAX_VALUE and Integer.parseInt(...).
Autoboxing & unboxing
The compiler silently converts primitive ↔ wrapper where needed — into a List<Integer>, or back out of one into an int. Convenient, but each boxing operation allocates an object, which matters in tight loops.
List<Integer> nums = new ArrayList<>();
nums.add(5); // autobox: int -> Integer
int first = nums.get(0); // unbox: Integer -> int
Integer boxed = null;
// int bad = boxed; // NullPointerException at unboxing!The Integer == trap
Java caches boxed Integer values from -128 to 127, so small ones can compare equal with == by accident while larger ones don't. This is an implementation detail, not a guarantee — always use .equals() (or unbox to int) to compare wrapper values.
Integer a = 100, b = 100;
System.out.println(a == b); // true (cached)
Integer x = 200, y = 200;
System.out.println(x == y); // false (not cached!)
System.out.println(x.equals(y)); // true — always correctQuick check
Quick check: What is the safest way to compare two Integer objects for equal value?
- == always works for Integer
- .equals(), or unbox both to int first
- compareTo() only, never equals()
- They can never be compared
Answer
.equals(), or unbox both to int first — == compares references and only accidentally works for the small cached range (-128..127). .equals() (or comparing primitive int values) is always correct.