Sitemap

Wrapper Classes in Java

5 min readOct 9, 2026

--

Java is often called an object-oriented programming language, but there is one thing that makes it different from being completely object-oriented: Java has primitive data types.

Primitive data types are:

byte
short
int
long
float
double
char
boolean

These are not objects.

For example:

int age = 22;

Here, age is a primitive variable, not an object.

So we can say:

Java is not considered purely object-oriented because it has primitive data types that are not objects.

But this raises an interesting question:

If Java is object-oriented, how can we represent primitive values as objects?

This is where Wrapper Classes come into the picture.

What are Wrapper Classes?

Wrapper classes are classes that provide an object representation of primitive data types.

Each primitive data type has a corresponding wrapper class.

PrimitiveWrapper ClassbyteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean

For example:

int age = 22;

Here age is a primitive.

But:

Integer age = 22;

Here age is an object of the Integer wrapper class.

Why do we use Primitive Data Types?

If wrapper classes give us objects, then why don’t we simply use wrapper classes everywhere?

One major reason is performance.

Primitive data types are generally more lightweight and efficient than objects.

For example:

int a = 10;
int b = 20;

Here Java stores primitive values directly without requiring an object to represent each value.

Creating and working with objects involves additional memory and object-management overhead.

Therefore, when we simply need to store and perform operations on values, primitives are often more efficient.

So:

Primitives are generally preferred when we don’t need an object.

Wrapper classes become useful when Java or an API specifically requires an object.

Why Do We Need Wrapper Classes?

There are many situations in Java where we need an object instead of a primitive.

One common example is Collections.

Consider an ArrayList:

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

We cannot write:

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

because Java Collections work with objects, not primitive types.

Therefore, we use:

Integer

instead of:

int

For example:

ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);

Here, Integer allows integer values to be represented as objects so they can be used with the collection.

Autoboxing

Now let’s understand autoboxing.

Autoboxing means Java automatically converts a primitive value into its corresponding wrapper object.

For example:

int number = 10;
Integer obj = number;

Here:

int → Integer

Java automatically converts the primitive int into an Integer object.

We don’t have to manually create the object.

This automatic conversion is called autoboxing.

Conceptually, Java does something similar to:

Integer obj = Integer.valueOf(number);

So:

int number = 10;
Integer obj = number;

is an example of autoboxing.

Unboxing

The opposite of autoboxing is called unboxing.

Unboxing means Java automatically converts a wrapper object back into its corresponding primitive type.

For example:

Integer obj = 10;
int number = obj;

Here:

Integer → int

Java automatically converts the Integer object into an int.

This is called unboxing.

Conceptually, Java does something similar to:

int number = obj.intValue();

Autoboxing and Unboxing Together

We can have both conversions in the same program.

int a = 10;          // primitive
Integer b = a;       // autoboxingint c = b;           // unboxing

So the flow is:

Autoboxing
int ───────────────→ Integer
↑ |
| |
└───────────────────────┘
Unboxing

Creating Wrapper Objects

Wrapper classes are classes, so they provide methods that we can use.

For example:

Integer number = Integer.valueOf(100);

We can also use:

Integer number = 100;

The second form uses autoboxing.

Get Aishu Reddy’s stories in your inbox

Join Medium for free to get updates from this writer.

For modern Java code, using valueOf() or autoboxing is preferred over explicitly creating wrapper objects using constructors.

For example, we should avoid:

Integer number = new Integer(100);

because wrapper constructors such as Integer(int) are deprecated.

Prefer:

Integer number = Integer.valueOf(100);

or simply:

Integer number = 100;

Useful Methods in Wrapper Classes

Wrapper classes provide many useful methods.

For example, Integer provides methods for converting strings into integers.

int number = Integer.parseInt("100");

Here:

String "100"
↓
Integer.parseInt()
↓
int 100

This is very useful when we receive numbers as strings.

For example:

String age = "22";
int number = Integer.parseInt(age);System.out.println(number + 5);

Output:

27

Without parsing, "22" + 5 would result in:

225

because "22" is a string.

valueOf() vs parseInt()

These two methods can sometimes be confusing.

parseInt()

Returns a primitive int.

int number = Integer.parseInt("100");

valueOf()

Returns an Integer object.

Integer number = Integer.valueOf("100");

So:

parseInt() → int
valueOf() → Integer

Wrapper Classes Can Contain null

Primitive variables cannot normally contain null.

For example:

int age = null;

This is invalid.

But an Integer can contain null:

Integer age = null;

This is useful when we need to represent the absence of a value.

For example, in databases, a column might contain NULL.

A Java Integer can represent that missing value:

Integer age = null;

while:

int age;

cannot represent null.

Wrapper Classes and Collections

One of the most common places where wrapper classes are used is the Java Collections Framework.

For example:

List<Integer> numbers = new ArrayList<>();

We use Integer instead of int.

But notice something interesting:

numbers.add(10);

We are passing an int, not explicitly creating an Integer.

Java automatically performs autoboxing:

10
↓
int
↓ autoboxing
Integer
↓
List<Integer>

Similarly, when we retrieve the value:

int number = numbers.get(0);

Java automatically performs unboxing:

Integer
↓ unboxing
int

This is one of the reasons autoboxing and unboxing are very useful.

Wrapper Class Caching

There is another interesting concept with wrapper classes.

Java may cache certain wrapper objects, especially for commonly used values.

For example, with Integer:

Integer a = 100;
Integer b = 100;
System.out.println(a == b);

This will typically print:

true

because commonly used Integer values are cached.

But:

Integer a = 200;
Integer b = 200;
System.out.println(a == b);

may print:

false

because two different objects may be created.

This is why we should not use == to compare wrapper objects when we want to compare their values.

Instead, use:

Integer a = 100;
Integer b = 100;
System.out.println(a.equals(b));

equals() compares the values.

This is an important point when working with wrapper classes.

The Big Picture

We can understand wrapper classes using this simple flow:

Primitive Data Types
|
| Need object representation
↓
Wrapper Classes
|
├── int → Integer
├── char → Character
├── double → Double
├── boolean → Boolean
└── ...

And Java makes the conversion easy:

Primitive                    Wrapper
int ───── autoboxing ───→ Integer
int ←──── unboxing ───── Integer

So the key idea is:

Wrapper classes provide object representations of primitive data types. They are especially useful when Java requires objects, such as when working with collections, and Java automatically converts between primitives and their wrapper classes through autoboxing and unboxing.

--

--

Aishu Reddy
Aishu Reddy

Written by Aishu Reddy

Turning ideas into code and bugs into lessons. 💻✨