If you are a Java coder sitting in a placement/internship interview and you use ArrayList to solve a question, and the interviewer asks, “What are autoboxing and unboxing, and where are they taking place in your code?” what would you do? Well, if you read this article, CONGRATULATIONS IN ADVANCE !!!, you are going to pass this question easily.
Prerequisites:
Java programming, Object-Oriented Programming (OOPS) in Java, and Overview of Generics in Java.
Topics Covered:
Wrapper Classes, Autoboxing and Unboxing in Java, and Boxing and Unboxing in Java (manually).
There are 8 wrapper classes for 8 primitive data types in Java. These are called wrapper classes because they create a wrapper around the primitive data types, i.e., a box around the primitive data types.
It is very simple to understand this concept. Let’s build our understanding through the Java Code given below:
Java Code (To explain Wrapping (Creating our own basic Wrapper Class))
class Main {
public static void main(String[] args) {
Number num1 = new Number(); //This will have a default value of 0
Number num2 = new Number(10); //This will have a value of 10
System.out.println(num1.x);
System.out.println(num2.x);
}
}
class Number {
int x;
Number() { //default constructor assigns initial value 0 to any number
x = 0;
}
Number(int x) { //parameterized constructor will assign our given value to the number
this.x = x;
}
}
You can refer to the code and compile and run it from here.
We know that primitive data types in Java are formed inside the Stack, whereas the Objects are formed in heap. So, we can see from the image above that due to object creation; it seems like there is a box or a wrapper around the primitive int datatype. This is almost what the wrapper classes do. Apart from just creating a box around the primitive data types, these Wrapper classes also have various other data members and methods, which makes them highly usable in Java.
Let us see a code to use the Integer Wrapper class in the same way as we used our Number class.
Java Code (to depict the use of Integer Class)
class Main {
public static void main(String args[]) {
// Your code goes here
Integer i1 = new Integer(10); //this is same as
// passing 10 in parameterized constructor
// of Number class in above example
System.out.println(i1); //This should print 10
}
}
You may refer to the
You might be wondering how the Integer class object i1, when passed to println function, got printed as it is not a primitive data type. If we want to define what should be printed when we use the System.out.println() code in Java, we need to override the toString() method in the class to achieve this.
The code given below shows the overriding of the toString() method for our Number class. We can say that the implementation of Wrapper classes is almost the same.
Java Code (For showing toString() Method)
class Main {
public static void main(String args[]) {
Number num1 = new Number(10);
System.out.println(num1);
//10 should be printed
}
}
class Number {
int x;
Number() { //default constructor assigns initial value 0 to any number
x = 0;
}
Number(int x) { //parameterized constructor will assign our given value to the number
this.x = x;
}
public String toString() {
return "" + x; //now value of x type casted as String will be printed
}
}
You can refer to the
Now that we have a fair idea about the wrapper classes let us move to autoboxing and unboxing.
Formal Definition: The process of automatic conversion of a primitive data type to an Object of Wrapper Class by the Java Compiler is called autoboxing.
Explanation: Let us take the example of our Number class that we made above. Can we write Number num = 10? The answer is NO! This is because num is a reference variable of the Number class, and it can hold the object of Number class, not a primitive data type. But in Java, we can write Integer i = 10, and this will not give any error.
This is because the Java compiler converts the int datatype literal 10 to an object of the Integer class with the value 10 automatically. This seems like the Java compiler automatically creates a box around the primitive datatype; hence the process is known as autoboxing. (Refer to the image below)
Autoboxing in Java takes place when any one of the following is done
1. When a primitive data type is passed as a parameter to a method/collection that expects an object of the corresponding wrapper class. For instance, In an ArrayList<Integer> list, we can directly add an integer because autoboxing takes place. Let us see a code for the same.
Java Code (for Autoboxing in Collections)
import java.util.*;
class Main {
public static void main(String args[]) {
// Your code goes here
ArrayList<Integer> list = new ArrayList<>();
for(int i=1;i<10;i++) list.add(i); //method add() takes input of
// primitive data type int
// but adds object of class Integer to the ArrayList
// this is autoboxing.
System.out.println(list);
System.out.println();
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.addLast(10); //autoboxing in addLast() method
linkedList.addFirst(5); //autoboxing in addFirst() method
System.out.println(linkedList);
}
}
You may play with the code
2. Also, autoboxing takes place when normally a primitive data type literal or variable is assigned to an object of Wrapper class.
Java Code (for Autoboxing with Variables)
class Main {
public static void main(String args[]) {
int x = 20;
Integer i1 = x; //auto boxing
System.out.println(i1); //this is not unboxing
//this is just overriding of toString()
}
}
Refer to the code
Formal Definition: When an object of a Wrapper class is converted to its primitive data type by the Java compiler, the process is called unboxing.
Explanation: Again, let us go with our Number class. Can we assign an object of type Number to an int variable? NO!! We can’t. It is, however, possible in Java to assign an Integer object to an int variable.
Java Code (for Unboxing)
class Main {
public static void main(String args[]) {
// Your code goes here
Integer i = 10; //autoboxing
int x = i; //unboxing
System.out.println(x);
}
}
You can play with the
Unboxing in Java happens in the following cases:
You have already seen one case in the code above i.e., when we assign an object of Wrapper class to a primitive data type variable.
Unboxing also happens when we pass an object of the Wrapper class to a method that expects a primitive data type variable. This is shown in the code below:
Java Code (to show Unboxing of Objects as Parameters)
class Main {
public static void main(String args[]) {
// Your code goes here
int sumOf2And3 = add(2,3);
System.out.println(sumOf2And3);
}
public static Integer add(Integer a, Integer b) {
int sum = a + b;
return sum;
}
}
Try creating some methods like this yourself too, and play with the above code
So, I hope that you have understood the concept of autoboxing and unboxing in Java.
Follow Up: Boxing and Unboxing can also be done manually by us in Java using some methods of Wrapper Classes. An example of the same is shown in the code below. Try out these and other codes with some other Wrapper classes as well.
Java Code (for Manual Boxing and Unboxing)
class Main {
public static void main(String args[]) {
// Your code goes here
int x = 10;
Integer i = Integer.valueOf(x); //boxing manually
System.out.println(i);
int y = i.intValue(); //unboxing manually
System.out.println(y);
}
}
You can refer to this code on our Online Java Compiler
I hope that you have understood all the concepts of Autoboxing and Unboxing along with Wrapper Classes and a little bit of extra detail and fun that we did by creating our own Wrapper class “Number.”