Java Wrapper Classes — Autoboxing, Unboxing & Parsing
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
- Collections only store objects —
List<int>is illegal; you needList<Integer>. - Generics require objects —
Optional<int>won’t compile. - Null representation — a primitive can’t be
null; a wrapper can. - 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
- Wrapper classes wrap primitives in objects for use in collections and generics.
- Autoboxing/unboxing happens automatically but has a performance cost.
- Use
parseInt()/parseDouble()to convert strings to primitives. - Integer cache covers -128 to 127 — always use
.equals()for comparison. - 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.