🎁 Wrapper Classes: Gift-Wrapping Your Primitives
Imagine you have a toy car. It’s small, fast, and does one thing—rolls around. But what if you want to put that toy car in a fancy gift box, add a bow, and give it special powers like a price tag or a return label?
That’s exactly what Wrapper Classes do in Java!
They take simple primitive values (like int, double, boolean) and wrap them in a beautiful object box. Now your primitive can do fancy things—join collections, have methods, and even become null.
🎯 What You’ll Learn
graph LR A[Wrapper Classes] --> B[Overview] A --> C[Autoboxing & Unboxing] A --> D[Parsing & Converting] A --> E[Integer Caching] A --> F[BigInteger & BigDecimal]
📦 Wrapper Classes Overview
The Simple Story
Java has 8 primitive types. Each one has a matching wrapper class:
| Primitive | Wrapper Class | Gift Box |
|---|---|---|
byte |
Byte |
📦 |
short |
Short |
📦 |
int |
Integer |
📦 |
long |
Long |
📦 |
float |
Float |
📦 |
double |
Double |
📦 |
char |
Character |
📦 |
boolean |
Boolean |
📦 |
Why Do We Need Them?
Problem: Collections like ArrayList only hold objects. Primitives aren’t objects!
// This WON'T work!
ArrayList<int> numbers; // ERROR!
// This WORKS!
ArrayList<Integer> numbers; // Perfect!
Creating Wrapper Objects
// Method 1: Using valueOf (recommended)
Integer age = Integer.valueOf(25);
Double price = Double.valueOf(9.99);
// Method 2: Direct assignment (autoboxing)
Integer count = 100;
Boolean isHappy = true;
Unwrapping: Getting the Primitive Back
Integer wrapped = Integer.valueOf(42);
int unwrapped = wrapped.intValue();
Double pi = Double.valueOf(3.14);
double piValue = pi.doubleValue();
🔄 Autoboxing and Unboxing
The Magic Trick
Remember manually wrapping and unwrapping? Java got tired of that too!
Autoboxing = Java automatically puts the primitive in a gift box Unboxing = Java automatically opens the gift box
Autoboxing in Action
// Before Java 5 (the hard way)
Integer num = Integer.valueOf(10);
// With Autoboxing (the easy way)
Integer num = 10; // Java wraps it!
It’s like having a robot helper that automatically gift-wraps your toys!
Unboxing in Action
Integer wrapped = 50;
// Automatic unboxing
int primitive = wrapped; // Java unwraps it!
// Works in math too!
int result = wrapped + 10; // = 60
Real Example: Collections
ArrayList<Integer> scores = new ArrayList<>();
// Autoboxing happens here
scores.add(95); // 95 → Integer.valueOf(95)
scores.add(87);
scores.add(92);
// Unboxing happens here
int firstScore = scores.get(0); // Integer → 95
⚠️ Watch Out: The Null Trap!
Integer maybeNull = null;
// DANGER! This crashes!
int value = maybeNull; // NullPointerException!
Rule: Always check for null before unboxing!
if (maybeNull != null) {
int value = maybeNull; // Safe!
}
🔄 Parsing and Converting Types
String → Number (Parsing)
Got a number hiding in a String? Let’s rescue it!
// String to int
String ageText = "25";
int age = Integer.parseInt(ageText);
// String to double
String priceText = "19.99";
double price = Double.parseDouble(priceText);
// String to boolean
String flag = "true";
boolean isOn = Boolean.parseBoolean(flag);
Number → String (Converting)
// Method 1: toString()
int score = 100;
String text1 = Integer.toString(score);
// Method 2: String.valueOf()
String text2 = String.valueOf(score);
// Method 3: Concatenation trick
String text3 = "" + score;
Number → Number
Integer num = 42;
// To other types
double d = num.doubleValue(); // 42.0
float f = num.floatValue(); // 42.0f
long l = num.longValue(); // 42L
⚠️ Parsing Dangers
// This crashes! "hello" isn't a number!
int bad = Integer.parseInt("hello");
// NumberFormatException!
// Always validate first or use try-catch
try {
int num = Integer.parseInt(userInput);
} catch (NumberFormatException e) {
System.out.println("Please enter a number!");
}
💰 Integer Caching
The Secret Optimization
Here’s a cool secret: Java is smart about memory!
When you create Integer values between -128 and 127, Java reuses the same objects!
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true! Same object!
Integer x = 200;
Integer y = 200;
System.out.println(x == y); // false! Different objects!
Why This Matters
Think of it like a candy store. Small candies (numbers -128 to 127) are kept in ready-made bags. Bigger orders need fresh packaging each time!
graph TD A[Integer.valueOf] --> B{Value in -128 to 127?} B -->|Yes| C[Return cached object] B -->|No| D[Create new object] C --> E[Same object reused] D --> F[New memory allocated]
The Right Way to Compare
Integer a = 100;
Integer b = 100;
// WRONG for large numbers!
if (a == b) { } // Compares references
// ALWAYS RIGHT!
if (a.equals(b)) { } // Compares values
Caching for Other Types
Byte: All values (-128 to 127)Short: -128 to 127Long: -128 to 127Character: 0 to 127Boolean:TRUEandFALSEonly
🔢 BigInteger and BigDecimal
When Regular Numbers Aren’t Enough
What if you need to count all the stars in the universe? Or calculate money with perfect accuracy?
Regular int maxes out at about 2 billion. Regular double has tiny rounding errors.
Enter the Big Heroes! 🦸♂️
BigInteger: For Huge Whole Numbers
import java.math.BigInteger;
// Create from String (for huge numbers)
BigInteger huge = new BigInteger(
"12345678901234567890"
);
// Create from int
BigInteger small = BigInteger.valueOf(100);
// Math operations
BigInteger a = new BigInteger("1000000000000");
BigInteger b = new BigInteger("9999999999999");
BigInteger sum = a.add(b);
BigInteger diff = b.subtract(a);
BigInteger product = a.multiply(b);
BigInteger quotient = b.divide(a);
BigDecimal: For Perfect Money Math
Ever notice 0.1 + 0.2 in Java equals 0.30000000000000004?
BigDecimal fixes this!
import java.math.BigDecimal;
// The problem with double
double bad = 0.1 + 0.2;
// Result: 0.30000000000000004 😱
// BigDecimal to the rescue!
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal good = a.add(b);
// Result: 0.3 ✨
// Money calculation
BigDecimal price = new BigDecimal("19.99");
BigDecimal quantity = new BigDecimal("3");
BigDecimal total = price.multiply(quantity);
// Result: 59.97 (exactly!)
BigDecimal Operations
BigDecimal x = new BigDecimal("100.50");
BigDecimal y = new BigDecimal("3");
// Addition
BigDecimal sum = x.add(y); // 103.50
// Subtraction
BigDecimal diff = x.subtract(y); // 97.50
// Multiplication
BigDecimal prod = x.multiply(y); // 301.50
// Division (specify scale and rounding)
BigDecimal div = x.divide(y, 2,
RoundingMode.HALF_UP); // 33.50
⚠️ BigDecimal Tips
// WRONG: Using double constructor
BigDecimal bad = new BigDecimal(0.1);
// Still has floating-point errors!
// RIGHT: Using String constructor
BigDecimal good = new BigDecimal("0.1");
// Perfect precision!
Comparing BigDecimal Values
BigDecimal a = new BigDecimal("10.0");
BigDecimal b = new BigDecimal("10.00");
// equals() checks scale too!
a.equals(b); // false! (different scale)
// compareTo() checks value only!
a.compareTo(b) == 0; // true! (same value)
🎯 Quick Summary
| Concept | What It Does | Example |
|---|---|---|
| Wrapper Class | Turns primitive into object | Integer x = 5; |
| Autoboxing | Auto wrap primitive | Integer x = 5; |
| Unboxing | Auto unwrap object | int y = x; |
| Parsing | String to number | Integer.parseInt("5") |
| Integer Cache | Reuses -128 to 127 | Use .equals() to compare! |
| BigInteger | Unlimited whole numbers | For very large integers |
| BigDecimal | Perfect decimal math | For money calculations |
🌟 Golden Rules
- Use
.equals()to compare wrapper objects, never== - Check for
nullbefore unboxing - Use BigDecimal for money—always!
- Create BigDecimal from String, not double
- Autoboxing is convenient but understand what happens underneath
You’ve just gift-wrapped your way to mastering Java Wrapper Classes! 🎁✨