PrepGo

Wrapper Classes - AP Computer Science A Study Guide

Written by AP Content Team, Verified for 2026 AP Exams, Last updated: July 2026

Learn with study guides reviewed by top AP teachers. This guide takes about 10 minutes to read.

Getting Started

In Java, we often distinguish between primitive types (like int and double) and object types (like String or custom classes). Data structures like ArrayList are designed to store collections of objects only. This presents a problem: how can we store a list of integers or decimal numbers? Wrapper classes provide the solution by "wrapping" a primitive value inside an object, making it compatible with ArrayList and other object-oriented features of Java.

What You Should Be Able to Do

  • Explain why wrapper classes are necessary for use with collections like ArrayList.

  • Declare and initialize an ArrayList that stores Integer or Double objects.

  • Describe the automatic processes of autoboxing (primitive to wrapper object) and unboxing (wrapper object to primitive).

  • Use the Integer class constants MIN_VALUE and MAX_VALUE to represent the bounds of the int data type.

  • Write code that correctly adds primitive values to an ArrayList of a wrapper type and retrieves them.

Key Concepts & Java Implementation

The Core Idea

A primitive type is a fundamental data type in Java that stores a single, simple value directly in memory. Examples include int, double, and boolean. An object, on the other hand, is an instance of a class, a more complex structure that bundles data (instance variables) and behaviors (methods) together.

The ArrayList class is designed to be a flexible container that can hold any kind of object. However, its internal structure is built to handle references to objects, not primitive values. Therefore, you cannot create an ArrayList of a primitive type, like int.


// This line of code will cause a compile-time error.

ArrayList<int> numberList = new ArrayList<int>(); 

To solve this, Java provides a wrapper class for each primitive type. A wrapper class is a class that encapsulates, or "wraps," a single primitive value inside an object. This allows us to treat a primitive value as if it were an object, making it compatible with ArrayList. The two most common wrapper classes you will use are Integer (for int) and Double (for double).

Syntax & Implementation

Java simplifies the use of wrapper classes with two automatic processes: autoboxing and unboxing.

  • Autoboxing: The automatic conversion that the Java compiler makes between a primitive type and its corresponding wrapper class object. When you try to add an int to an ArrayList<Integer>, Java automatically "boxes" the int into a new Integer object for you.

  • Unboxing: The automatic conversion that the Java compiler makes from a wrapper class object back to its corresponding primitive type. When you retrieve an Integer object from an ArrayList and assign it to an int variable, Java automatically "unboxes" the value for you.

Syntax Table: Common Wrapper Classes

Primitive TypeWrapper ClassJava Declaration Example
intIntegerArrayList<Integer> scores = new ArrayList<>();
doubleDoubleArrayList<Double> prices = new ArrayList<>();

Annotated Java Examples

The following example demonstrates creating an ArrayList of Integer objects and leveraging autoboxing and unboxing.


import java.util.ArrayList;


public class ScoreTracker {

    public static void main(String[] args) {

        // 1. Declare and initialize an ArrayList to hold Integer objects.

        ArrayList<Integer> scores = new ArrayList<>();


        // 2. Add primitive int values. Autoboxing handles the conversion.

        scores.add(95);   // Java converts int 95 to an Integer object

        scores.add(88);   // Java converts int 88 to an Integer object

        scores.add(72);   // Java converts int 72 to an Integer object


        System.out.println("Scores in list: " + scores);


        // 3. Retrieve a value and perform a calculation. Unboxing handles the conversion.

        int firstScore = scores.get(0); // Java converts the Integer object at index 0 to an int

        int total = 0;


        // 4. Use a for-each loop, which also uses unboxing.

        for (Integer currentScore : scores) {

            // The 'currentScore' Integer object is unboxed to an int for the addition.

            total += currentScore; 

        }


        System.out.println("First score: " + firstScore);

        System.out.println("Total of all scores: " + total);

    }

}

Output of the code:


Scores in list: [95, 88, 72]

First score: 95

Total of all scores: 255

The Integer class also provides useful constants, MIN_VALUE and MAX_VALUE, which hold the smallest and largest possible values for the int data type.


public class IntegerBounds {

    public static void main(String[] args) {

        // These are public static final constants of the Integer class.

        int smallestInt = Integer.MIN_VALUE;

        int largestInt = Integer.MAX_VALUE;


        System.out.println("The smallest possible int is: " + smallestInt);

        System.out.println("The largest possible int is: " + largestInt);

    }

}

Output of the code:


The smallest possible int is: -2147483648

The largest possible int is: 2147483647

Tracing & Analysis

Let's trace the execution of adding and retrieving values from an ArrayList<Integer>.

Code to Trace:


ArrayList<Integer> list = new ArrayList<>();

list.add(10);

list.add(20);

int x = list.get(0);

int y = list.get(1);

int sum = x + y;

Execution Trace:

Line of Codelist (State)x (Value)y (Value)sum (Value)Notes
ArrayList<Integer> list = new ArrayList<>();[] (empty)uninitializeduninitializeduninitializedAn empty ArrayList of Integer objects is created.
list.add(10);[10]uninitializeduninitializeduninitializedAutoboxing: int 10 is converted to an Integer object and added.
list.add(20);[10, 20]uninitializeduninitializeduninitializedAutoboxing: int 20 is converted to an Integer object and added.
int x = list.get(0);[10, 20]10uninitializeduninitializedUnboxing: The Integer object at index 0 is converted to int 10.
int y = list.get(1);[10, 20]1020uninitializedUnboxing: The Integer object at index 1 is converted to int 20.
int sum = x + y;[10, 20]102030The two primitive int values are added.

Analysis:

While autoboxing and unboxing are extremely convenient, it is crucial to remember that they are not "magic." The compiler is generating code to create new objects (Integer or Double) and to call methods to extract their primitive values. This is a seamless process, but understanding the underlying object creation and method calls is key to mastering how Java manages data.

Java Syntax Quick-Reference

  • Integer: The wrapper class for the int primitive type. Used for storing integer values in object-based collections like ArrayList.

  • Double: The wrapper class for the double primitive type. Used for storing floating-point values in object-based collections.

  • Integer.MIN_VALUE: A public static final int constant that holds the minimum value an int can represent (-231).

  • Integer.MAX_VALUE: A public static final int constant that holds the maximum value an int can represent (231 - 1).

Core Code Examples & Terminology

  • Primitive Type: A fundamental data type that is not an object and stores a value directly in memory, such as int, double, or boolean.

  • Wrapper Class: A class that encapsulates a primitive data type within an object, allowing the primitive to be used in contexts that require objects (e.g., ArrayList).

  • Autoboxing: The automatic conversion of a primitive value into an instance of its corresponding wrapper class (e.g., int to Integer).

  • Unboxing: The automatic conversion of a wrapper class object back into its corresponding primitive value (e.g., Integer to int).

  • Declaring an ArrayList for Integers:

    
    ArrayList<Integer> studentAges = new ArrayList<>();
    

    This code creates an empty list that is specifically typed to hold Integer objects.

  • Using Autoboxing:

    
    ArrayList<Integer> numbers = new ArrayList<>();
    
    numbers.add(42); // The int 42 is autoboxed into an Integer object.
    

    This code demonstrates adding a primitive int directly to an ArrayList<Integer>, relying on the compiler to perform the conversion.

  • Using Unboxing:

    
    int myNum = numbers.get(0); // The Integer object is unboxed into an int.
    

    This code retrieves an Integer object from the list and assigns its value to a primitive int variable, relying on unboxing.

Core Skill Check

  • Code Tracing: What is the final value of sum after this Java code runs: ArrayList<Integer> vals = new ArrayList<>(); vals.add(5); vals.add(12); int sum = vals.get(0) + vals.get(1);?

    • Answer: 17
  • Debugging: Identify the compile-time error in this Java code: ArrayList<double> measurements = new ArrayList<>();.

    • Answer: The type parameter for ArrayList cannot be a primitive type (double). It must be a class name, such as its wrapper class Double.
  • Application: Write a single line of Java code that adds the integer 100 to an existing ArrayList<Integer> named highScores.

    • Answer: highScores.add(100);

Common Misconceptions & Errors

  1. Using Primitives with ArrayList: A common mistake is trying to declare an ArrayList with a primitive type, like ArrayList<int>. This will always cause a compile-time error because generic type parameters must be object types. Always use the wrapper class (Integer, Double, etc.).

  2. Confusing int and Integer: While autoboxing makes them seem interchangeable, they are different. int is a primitive value. Integer is an object that holds an int value. An Integer variable can also be null, which can lead to a NullPointerException if you try to unbox it.

  3. Forgetting Unboxing Occurs: When performing arithmetic with a wrapper object (e.g., Integer num = 5; int result = num * 2;), remember that the Integernum is first unboxed to a primitive int before the multiplication can happen.

Summary

Wrapper classes bridge the gap between Java's primitive types and its object-oriented data structures. Because collections like ArrayList can only store objects, we use wrapper classes like Integer and Double to contain primitive int and double values. The Java compiler makes this process seamless through autoboxing (automatically converting a primitive to a wrapper object) and unboxing (automatically converting a wrapper object back to a primitive). This allows you to write clean, readable code that treats primitive values and objects in a unified way within collections.