ReviseAlgo Logo

Basic Syntax

Wrapper Classes

Explore the object representations of primitive types, covering autoboxing, unboxing, caching mechanisms, and performance overheads.

Interview: Crucial for understanding collections integration, NullPointerExceptions during unboxing, and the Integer Cache range pool.

Last Updated: June 13, 2026 12 min read

In Java, primitive data types (like int, double, and char) are not objects. While they are highly performant and memory-efficient, they cannot be used in Java collections (like ArrayList or HashMap) or as nullable values. Wrapper Classes wrap primitives in objects, bridging the gap between primitive efficiency and object-oriented flexibility.

Core Idea

Each primitive has a corresponding Wrapper Class (e.g., int to Integer). Autoboxing and unboxing automate conversion between the two.

Why It Matters

Java's generics require object types. Without wrappers, you cannot store primitives in standard Java collections. Wrappers also support utility methods and null values.

Interview Lens

Expect deep-dive questions on the Integer Cache (value pooling), memory overhead differences, and unboxing-induced NullPointerExceptions.

Primitive to Wrapper Mapping

Java provides eight wrapper classes in the java.lang package:

Primitive Type Wrapper Class Size in Memory (Primitive) Size in Memory (Wrapper)
byte Byte 1 byte ~16 bytes (Heap overhead)
short Short 2 bytes ~16 bytes
int Integer 4 bytes ~16 bytes
long Long 8 bytes ~24 bytes
float Float 4 bytes ~16 bytes
double Double 8 bytes ~24 bytes
char Character 2 bytes ~16 bytes
boolean Boolean 1 bit (JVM dependent) ~16 bytes

Autoboxing and Unboxing

Java automatically converts between primitive types and their corresponding wrapper classes:

  • Autoboxing: The automatic conversion that the Java compiler makes between the primitive type and its corresponding object wrapper class. For example, converting an int to an Integer. Under the hood, the compiler inserts calls to Integer.valueOf(primitiveValue).
  • Unboxing: The automatic conversion of wrapper class objects back into primitives. For example, converting an Integer to an int. Under the hood, the compiler inserts calls to integerObject.intValue().

The Integer Cache (Value Pooling)

To save memory and improve performance, Java pools/caches wrapper instances of low-value integer classes. When using autoboxing or calling Integer.valueOf(), Java returns cached references for values in the range -128 to 127 (inclusive).

This caching behavior applies to:

  • Byte, Short, Long, Integer (range -128 to 127)
  • Character (range 0 to 127)
  • Boolean (caching TRUE and FALSE constants)

Comparing wrapper objects outside this range using the identity operator (==) will compare their heap memory references and evaluate to false, even if their wrapped numerical values are identical.

Common Pitfalls

  • Comparing Wrappers with ==: Using == compares references, not values. For example, Integer x = 200, y = 200; x == y is false. Always use x.equals(y) to compare object values.
  • NullPointerExceptions (NPE) on Unboxing: Trying to unbox a wrapper object that is null causes a runtime NullPointerException. For example, Integer x = null; int y = x; will compile but crash at runtime.
  • Performance and GC Overhead in Loops: Autoboxing inside loops creates a large number of temporary objects, triggering frequent garbage collection cycles. For example, declaring Long sum = 0L; instead of long sum = 0L; inside a loop with millions of iterations.

Best Practices

  • Use primitives for local variables, loop indexes, and mathematical calculations where null is not needed.
  • Use wrapper classes for fields in domain objects/entities where null represents a database NULL or missing value.
  • Always compare wrapper values using .equals(), never ==, unless you specifically need reference identity.
  • Perform null checks on wrapper objects before unboxing or using them in conditional statements.
  • Use utility parsing methods like Integer.parseInt(str) (returns primitive int) instead of Integer.valueOf(str) (returns Integer object) when you need a primitive.

Interview-Relevant Information

Q1: Why does Integer a = 100, b = 100; a == b evaluate to true, but Integer c = 200, d = 200; c == d evaluates to false?
Answer: Java caches Integer wrapper class objects for values between -128 and 127. Autoboxing 100 returns the same cached reference from the pool, so a == b is true. For 200, autoboxing generates new object references on the heap, so c == d compares memory addresses and yields false.

Q2: What happens when you execute: Double d = null; double val = d; ?
Answer: It compiles successfully because unboxing is supported. However, at runtime, the JVM calls d.doubleValue() to retrieve the primitive. Since d is null, this invocation throws a NullPointerException.

Q3: Can the Integer Cache range limits be adjusted?
Answer: Yes. You can change the upper limit of the Integer cache by passing the JVM argument -XX:AutoBoxCacheMax=<size>. The lower limit is permanently fixed at -128.

Quick Checklist

Can you explain autoboxing/unboxing mechanisms, define the caching range for Integer, Byte, and Character, explain how comparison behavior changes across the cache boundary, and prevent unboxing NPEs? If yes, you have mastered Wrapper Classes.

Use Cases

Using primitive fields in database entities where null represents an unassigned or empty state.

Storing integer counters or boolean markers in ArrayLists, HashMaps, or other Generics collections.

Common Mistakes

Accidentally comparing wrapper numbers using comparison operators (like ==) inside configuration files or critical business logic.

Declaring variables as wrappers (e.g., Double) inside recursive or tight computational loops, degrading garbage collection performance.