Introduction
Java has two categories of data types: primitives (int, double, boolean, etc.) and objects (instances of classes). Sometimes we need to treat primitive values as objects—for example, to store them in ArrayLists or use object-specific methods. Wrapper classes solve this problem by providing object versions of primitive types.
Topic 4.7 focuses on two wrapper classes: Integer (wraps int) and Double (wraps double). We'll explore how Java automatically converts between primitives and wrappers through autoboxing and unboxing, and how to parse strings into numeric values.
What are Wrapper Classes?
Wrapper classes are object types that "wrap" primitive values, allowing primitives to be treated as objects.
Each primitive type has a corresponding wrapper class:
| Primitive | Wrapper Class |
|---|---|
| int | Integer |
| double | Double |
| boolean | Boolean |
| char | Character |
For AP Computer Science A, we focus on Integer and Double.
The Integer Class
The Integer class and Double class are part of the java.lang package. No import statement is needed—these classes are automatically available.
An Integer object is immutable, meaning once an Integer object is created, its attributes cannot be changed. The value stored inside cannot be modified.
Creating Integer Objects
Integer num1 = new Integer(42); // Wraps the int value 42
Integer num2 = new Integer(100);
Note: The Integer(int) constructor is deprecated in newer Java versions, but you should understand it for the AP exam. Modern code uses autoboxing instead (explained below).
Integer is Immutable
Integer x = new Integer(5);
// There's no way to change x's internal value to 10
// x always contains 5 unless you reassign x to a different Integer objectThis differs from mutable objects where you can call methods to change their state.
The Double Class
Works identically to Integer but wraps double values.
A Double object is immutable, meaning once a Double object is created, its attributes cannot be changed.
Double price = new Double(19.99);
Double temperature = new Double(72.5);
Autoboxing
Autoboxing is the automatic conversion that the Java compiler makes between primitive types and their corresponding object wrapper classes.
The Java compiler applies autoboxing when a primitive value is:
- Passed as a parameter to a method that expects an object of the corresponding wrapper class
- Assigned to a variable of the corresponding wrapper class
Examples of Autoboxing
// Autoboxing: int to Integer
int primitive = 42;
Integer wrapped = primitive; // Automatically converts
// Autoboxing in method call
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(50); // int 50 automatically becomes IntegerBehind the scenes, Java converts int to Integer:
Integer wrapped = Integer.valueOf(primitive);Why Autoboxing Matters
ArrayLists can only store objects, not primitives:
// This won't work:
ArrayList<int> numbers; // WRONG - can't use primitives// Must use wrapper class:
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(10); // Autoboxing converts int 10 to IntegerUnboxing
Unboxing is the automatic conversion that the Java compiler makes from the wrapper class to the primitive type.
The Java compiler applies unboxing when a wrapper class object is:
- Passed as a parameter to a method that expects a value of the corresponding primitive type
- Assigned to a variable of the corresponding primitive type
Examples of Unboxing
// Unboxing: Integer to int
Integer wrapped = 42;
int primitive = wrapped; // Automatically converts// Unboxing in arithmetic
Integer a = 10;
Integer b = 20;
int sum = a + b; // Both unbox to int, then addBehind the scenes, Java calls:
int primitive = wrapped.intValue();Complete Autoboxing/Unboxing Example
ArrayList<Integer> scores = new ArrayList<Integer>();
// Autoboxing: int to Integer
scores.add(85); // int 85 becomes Integer
scores.add(92);
scores.add(78);
// Unboxing: Integer to int
int firstScore = scores.get(0); // Integer becomes int
int sum = 0;
for (Integer score : scores)
{
sum += score; // Each Integer unboxes to int
}
double average = (double) sum / scores.size();
Parsing Strings to Numbers
Often data comes as strings (from files, user input, etc.) but we need numeric values. The Integer and Double classes provide static methods for conversion.
Integer.parseInt
The following class Integer method converts strings to integers:
static int parseInt(String s) — returns the String argument as an int.
String text = "42";
int number = Integer.parseInt(text);
System.out.println(number + 10); // 52
Important: The string must contain a valid integer, or NumberFormatException occurs:
Integer.parseInt("123"); // OK: returns 123
Integer.parseInt("3.14"); // ERROR: not an integer
Integer.parseInt("abc"); // ERROR: not a number
Double.parseDouble
The following class Double method converts strings to doubles:
static double parseDouble(String s) — returns the String argument as a double.
String text = "3.14";
double number = Double.parseDouble(text);
System.out.println(number * 2); // 6.28Examples:
Double.parseDouble("19.99"); // OK: returns 19.99
Double.parseDouble("100"); // OK: returns 100.0
Double.parseDouble("2.5e3"); // OK: returns 2500.0
Double.parseDouble("hello"); // ERROR: NumberFormatException
Practical Use: Reading File Data
// File contains: "Alice,85,92,78"
String line = scan.nextLine();
String[] parts = line.split(",");
String name = parts[0]; // "Alice"
int score1 = Integer.parseInt(parts[1]); // 85
int score2 = Integer.parseInt(parts[2]); // 92
int score3 = Integer.parseInt(parts[3]); // 78
double avg = (score1 + score2 + score3) / 3.0;
Common Use Cases
Use Case 1: ArrayList of Numbers
ArrayList<Integer> ages = new ArrayList<Integer>();
ages.add(15); // Autoboxing
ages.add(22);
ages.add(17);
int youngest = ages.get(0); // Unboxing
for (int age : ages)
{ // Unboxing in loop
System.out.println(age);
}
Use Case 2: Converting String Input
// Process comma-separated numbers
String input = "10,20,30,40";
String[] tokens = input.split(",");
int sum = 0;
for (String token : tokens)
{
sum += Integer.parseInt(token);
}
System.out.println("Sum: " + sum); // Sum: 100
Use Case 3: Null Values
Wrapper classes can be null, primitives cannot:
Integer score = null; // OK - reference can be null
int value = null; // ERROR - primitives can't be null
This is useful for representing "no value" or "missing data":
ArrayList<Integer> scores = new ArrayList<Integer>();
scores.add(85);
scores.add(null); // Represents missing score
scores.add(92);
for (Integer score : scores)
{
if (score != null) // Check for missing data
{
System.out.println(score);
}
}
Wrapper Class Methods
Besides parsing, wrapper classes provide utility methods:
Integer.MAX_VALUE // Largest int: 2147483647
Integer.MIN_VALUE // Smallest int: -2147483648
Double.MAX_VALUE // Largest double
Double.MIN_VALUE // Smallest positive double
Integer a = 42;
String s = a.toString(); // Converts to "42"Common Mistakes
Mistake 1: Confusing parse methods
// WRONG - parseInt returns int, not Integer
Integer num = Integer.parseInt("42"); // Works due to autoboxing
int value = Integer.valueOf("42"); // Works due to unboxing
// But mixing them up shows misunderstanding
Mistake 2: NullPointerException with unboxing
Integer score = null;
int value = score; // ERROR: can't unbox null
Mistake 3: Forgetting parse methods are static
String text = "100";
// WRONG - parseInt is static, not instance method
// text.parseInt(); // Doesn't exist
// CORRECT
int num = Integer.parseInt(text);
