Java Wrapper Classes — Autoboxing, Unboxing & Parsing

3 minute read

Java is an object-oriented language, but its 8 primitive types (int, double, boolean, etc.) are not objects. Wrapper classes bridge this gap by wrapping primitives in objects.


Primitive → Wrapper Mapping

Primitive Wrapper Size
byte Byte 8 bit
short Short 16 bit
int Integer 32 bit
long Long 64 bit
float Float 32 bit
double Double 64 bit
char Character 16 bit
boolean Boolean —

Why Wrappers Exist

  1. Collections only store objects — List<int> is illegal; you need List<Integer>.
  2. Generics require objects — Optional<int> won’t compile.
  3. Null representation — a primitive can’t be null; a wrapper can.
  4. Utility methods — Integer.parseInt(), Integer.MAX_VALUE, etc.

Autoboxing and Unboxing

Java automatically converts between primitives and wrappers:

Autoboxing (primitive → wrapper)

Integer num = 42;         // compiler: Integer.valueOf(42)
List<Integer> list = new ArrayList<>();
list.add(10);             // autoboxed

Unboxing (wrapper → primitive)

Integer wrapped = 42;
int primitive = wrapped;  // compiler: wrapped.intValue()

int sum = wrapped + 8;    // unboxed, then added

Creating Wrapper Objects

valueOf() — Preferred (Uses Cache)

Integer a = Integer.valueOf(42);
Integer b = Integer.valueOf("42");
Double  d = Double.valueOf(3.14);
Boolean t = Boolean.valueOf("true");

Constructor — Deprecated Since Java 9

Integer n = new Integer(42);  // ⚠️ Deprecated — use valueOf()

Parsing Strings to Primitives

int    i = Integer.parseInt("42");
double d = Double.parseDouble("3.14");
long   l = Long.parseLong("1000000");
boolean b = Boolean.parseBoolean("true");

// parseInt with radix
int hex = Integer.parseInt("FF", 16);   // 255
int bin = Integer.parseInt("1010", 2);  // 10

Handling Bad Input

try {
    int n = Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Not a valid number");
}

Useful Constants

Integer.MAX_VALUE   // 2,147,483,647
Integer.MIN_VALUE   // -2,147,483,648
Long.MAX_VALUE      // 9,223,372,036,854,775,807
Double.MAX_VALUE    // 1.7976931348623157E308
Double.NaN          // Not a Number
Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY

Conversion Methods

Integer n = 42;

n.intValue()      // 42 (int)
n.doubleValue()   // 42.0 (double)
n.toString()      // "42" (String)

Integer.toString(42)       // "42"
Integer.toHexString(255)   // "ff"
Integer.toBinaryString(10) // "1010"
Integer.toOctalString(8)   // "10"

Integer Caching (-128 to 127)

Java caches Integer values from -128 to 127:

Integer a = 127;
Integer b = 127;
System.out.println(a == b);   // true  (same cached object)

Integer c = 128;
Integer d = 128;
System.out.println(c == d);   // false (different objects!)
System.out.println(c.equals(d)); // true (same value)

Always use .equals() to compare wrapper objects, not ==.

This caching also applies to Byte, Short, Long (-128 to 127), Character (0 to 127), and Boolean.


Null Safety — Wrappers vs Primitives

Integer count = null;   // ✅ valid
int total = count;      // ❌ NullPointerException (unboxing null)

Always check for null before unboxing:

if (count != null) {
    int total = count;
}

// Or use Optional
Optional.ofNullable(count).orElse(0);

When to Use Wrapper vs Primitive

Use Primitive When Use Wrapper When
Performance matters Value might be null
No null needed Storing in collections
Simple local calculations Using generics
Array elements (primitive arrays) Map keys/values

Default to primitives. Use wrappers only when you need nullability or generics.


Comparison Methods

Integer.compare(10, 20)    // -1 (negative: a < b)
Integer.compare(20, 20)    //  0
Integer.compare(30, 20)    //  1 (positive: a > b)

Integer.max(10, 20)        // 20
Integer.min(10, 20)        // 10
Integer.sum(10, 20)        // 30

Common Mistakes

Mistake Problem Fix
== on wrappers Compares references Use .equals()
Unboxing null NullPointerException Null-check first
new Integer(42) Deprecated, bypasses cache Use Integer.valueOf(42)
Wrappers in tight loops Autoboxing creates garbage Use primitives

Key Takeaways

  1. Wrapper classes wrap primitives in objects for use in collections and generics.
  2. Autoboxing/unboxing happens automatically but has a performance cost.
  3. Use parseInt() / parseDouble() to convert strings to primitives.
  4. Integer cache covers -128 to 127 — always use .equals() for comparison.
  5. Default to primitives — use wrappers only when nullability or generics require it.

What’s Next?

Next: Java Optional — eliminate NullPointerException with Java’s built-in null-safety tool.

Updated: