Wrapper Classes in Java

1. Overview

As the name suggests, wrapper classes are objects encapsulating primitive Java types.

Each Java primitive has a corresponding wrapper:

  • boolean, byte, short, char, int, long, float, double 
  • Boolean, Byte, Short, Character, Integer, Long, Float, Double

These are all defined in the java.lang package, hence we don’t need to import them manually.

2. Wrapper Classes

“What’s the purpose of a wrapper class?”. It’s one of the most common Java interview questions.

Basically, generic classes only work with objects and don’t support primitives. As a result, if we want to work with them, we have to convert primitive values into wrapper objects.

For example, the Java Collection Framework works with objects exclusively. Long back when (prior to Java 5, almost 15 years back) there was no autoboxing and we, for example, couldn’t simply call add(5) on a collection of Integers.

At that time, those primitive values needed to be manually converted to corresponding wrapper classes and stored in collections.

Today, with autoboxing, we can easily do ArrayList.add(101) but internally Java converts the primitive value to an Integer before storing it in the ArrayList using the valueOf() method.

3. Primitive to Wrapper Class Conversion

Now the big question is: how do we convert a primitive value to a corresponding wrapper class e.g. an int to Integer or a char to Character?

Well, we can either use constructor or static factory methods to convert a primitive value to an object of a wrapper class.

As of Java 9, however, constructors for many boxed primitives such as Integer or Long have been deprecated.

So it’s highly recommended to only use the factory methods on new code.

Let’s see an example of converting an int value to an Integer object in Java:

Integer object = new Integer(1);

Integer anotherObject = Integer.valueOf(1);

The valueOf() method returns an instance representing the specified int value.

It returns cached values which makes it efficient. It always caches values between -128 to 127 but can also cache other values outside this range.

Similarly, we can also convert boolean to Boolean, byte to Byte, char to Character, long to Long, float to Float, and double to Double. Though if we have to convert String to Integer then we need to use parseInt() method because String isn’t a wrapper class.

On the other hand, to convert from a wrapper object to a primitive value, we can use the corresponding method such as intValue(), doubleValue() etc:

int val = object.intValue();

A comprehensive reference can be found here.

4. Autoboxing and Unboxing

In the previous section, we showed how to manually convert a primitive value to an object.

After Java 5, this conversion can be done automatically by using features called autoboxing and unboxing.

“Boxing” refers to converting a primitive value into a corresponding wrapper object. Because this can happen automatically, it’s known as autoboxing.

Similarly, when a wrapper object is unwrapped into a primitive value then this is known as unboxing.

What this means in practice is that we can pass a primitive value to a method which expects a wrapper objector assign a primitive to a variable which expects an object:

List<Integer> list = new ArrayList<>();
list.add(1); // autoboxing

Integer val = 2; // autoboxing

In this example, Java will automatically convert the primitive int value to the wrapper.

Internally, it uses the valueOf() method to facilitate the conversion. For example, the following lines are equivalent:

Integer value = 3;

Integer value = Integer.valueOf(3);

Though this makes conversion easy and codes more readable, there are some cases where we shouldn’t use autoboxing e.g. inside a loop.

Similar to autoboxing, unboxing is done automatically when passing an object to a method that expects a primitive or when assigning it to a primitive variable:

Integer object = new Integer(1); 
int val1 = getSquareValue(object); //unboxing
int val2 = object; //unboxing

public static int getSquareValue(int i) {
    return i*i;
}

Basically, if we write a method that accepts a primitive value or wrapper object, we can still pass both values to them. Java will take care of passing the right type e.g. primitive or wrapper depending upon context.

5. Conclusion

In this quick tutorial, we talked about wrapper classes in Java, as well as the mechanism of autoboxing and unboxing.

Related posts:

A Guide to JUnit 5
Java Program to Perform Left Rotation on a Binary Search Tree
Java Program to Implement LinkedHashMap API
Guide to the Synchronized Keyword in Java
Java Program to Find k Numbers Closest to Median of S, Where S is a Set of n Numbers
Java Program to Implement Merge Sort Algorithm on Linked List
Java Program to Implement Bloom Filter
Giới thiệu Google Guice – Dependency injection (DI) framework
Convert a Map to an Array, List or Set in Java
Java Program to Implement Levenshtein Distance Computing Algorithm
Instance Profile Credentials using Spring Cloud
Java Program to Implement Sorted Array
List Interface trong Java
Java Program to Implement Max Heap
Form Validation with AngularJS and Spring MVC
Assert an Exception is Thrown in JUnit 4 and 5
Luồng Daemon (Daemon Thread) trong Java
Overflow and Underflow in Java
File Upload with Spring MVC
Jackson Exceptions – Problems and Solutions
Java Program to Solve the 0-1 Knapsack Problem
Checking for Empty or Blank Strings in Java
Working With Maps Using Streams
Java Program to Generate All Possible Combinations Out of a, b, c, d, e
Jackson – JsonMappingException (No serializer found for class)
Java Program to Perform Cryptography Using Transposition Technique
Java Program to Generate All Possible Subsets with Exactly k Elements in Each Subset
Java Program to find the peak element of an array using Binary Search approach
Convert String to int or Integer in Java
Java Program to Implement ConcurrentLinkedQueue API
The DAO with Spring and Hibernate
Java toString() Method