Autoboxing and Unboxing in Java

The presence of primitive types in Java led to the rise of wrapper classes. The two components, autoboxing and unboxing, are present in this class. This article will dive deep into the autoboxing and unboxing concepts in Java.

What is autoboxing in java?

The process of converting a primitive value into an instance of the wrapper class is known as autoboxing. Example: Converting int to Integer.

The autoboxing takes place in three different cases:

Case 1: Passed as a parameter to a method that requires an object of the wrapper class.

Sample program to implement case 1:

public class FirstCode{
public static void method1(Integer num){
Systemout.println(num);
}
public static void main(String args[]){
method1(10); // the value is passed as int but the compiler converts it as Integer object. 
}
}

Output:

10

Case 2: Assigned to a variable of the corresponding wrapper class.

Sample program to implement case 2:

public class FirstCode{
public static void main(String args[]){
Integer num = 20;
Long num2 = 88L;
System.out.println(num);
System.out.println(num2);
}
}

Output:

20
88

Case 3: Autoboxing takes place while working with collection framework classes.

Sample program to implement case 3:

import java.util.ArrayList;
public class FirstCode{
public static void main(String args[]){
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(10);
al.add(20);
System.out.println(al);
}
}

Output:

[10,20]

Java program to illustrate the use of Autoboxing in Java:

import java.util.*;
public class FirstCode{
public static void main(String args[]){
Stack<Integer>stack = new Stack<>();
int x=10;
int y=18;
stack.push(x);
stackpush(y);
System.out.println(stack.pop());
}
}

Output:

18

This program lets us perform a stack operation that can access only Integer values. You might have noticed that the compiler did not throw any errors when we precisely asked it to push the primitive data types in the stack. This is due to autoboxing; the compiler converts the primitive data type to its respective wrapper class by default.

Autoboxing with Method Overloading in Java:

To use autoboxing and unboxing in unison in Java, we must follow certain rules.

a. Boxing gets lower preference when compared to Widening:

We can call the widening function when the function overloading has a parameter that is of upper type-casting involved. Here is a sample program to implement it.

public class FirstCode{
public static void conversion(Float f){
System.out.println(“The value is converted to its wrapper class”);
}                                                   
public static void conversion(float f){
System.out.println(“The value is converted to a wider primitive datatype”);
}
public static void main(String args[]){
int a =14;
conversion(a);
}
}   

Output:

The value is converted to a wider primitive data type

b. Boxing is preferred over var args:

The compiler chooses boxing and unboxing over varargs. Thus it binds the method call to achieve boxing.

public class FirstCode{
public static void conversion(Float f){
System.out.println(“The function with one parameter is executed”);
}                                                   
public static void conversion(float… f){
System.out.println(“The function with variable arguments is executed”);
}
public static void main(String args[]){
float a =14;
conversion(a);
}
}   

Output:

The function with one parameter is executed

c. Widening beats varargs:

The compiler chooses the widening of variables in contrast to varargs. Thus, it does the widening instead of getting the parameters as a variable argument.

public class FirstCode{
public static void conversion(Float f){
System.out.println(“The function with one parameter is executed”);
}                                                   
public static void conversion(float… f){
System.out.println(“The function with variable arguments is executed”);
}
public static void main(String args[]){
float a =14;
conversion(a);
}
}   

Output:

The function with widened parameter is executed

What is unboxing in java?

As mentioned earlier, autoboxing does the role of converting a primitive value to an object of the corresponding wrapper class. On the other hand, autoboxing does vice versa of it.
It converts the object of the wrapper type to its corresponding primitive value. For example: Converting Integer to int.

Here is a table that portrays the corresponding conversion type:

Primitive Type Wrapper Class
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double

Unboxing takes place in three different cases:

Case 1: The object is passed as a parameter to a method that requires a value of the primitive type.

Sample code to explain case 1:

public class FirstCode{
public static void method1(int num){
System.out.println(num);
}
public static void main(String args[]){
Integer obj = new Interger(50); // The Integer wrapper class is converted to int
method1(int obj);
}
}

Output:

50

Case 2: It is assigned to a variable of the corresponding primitive type.

Sample program to implement case 2:

public class FirstCode{
public static void main(String args[]){
Integer obj = new Integer(50);
int num = obj; //unboxing object to primitive type
System.out.println(num);
}
}

Output:

50

Case 3: Unboxing takes place even while dealing with collection classes.

Sample program to implement case 3:

import java.util.ArrayList;
pubic class FirstCode{
public static void main(String args[]){
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(5);
int num = (int) al.get(0);
System.out.println(num);
}
}

Output:

5

Example of Unboxing in Java:

import java.util.*;
public class FirstCode{
public int add(Integer n1, Integer n2){
return n1+n2;
}
public static void main(String args[]){
Stack<Integer>stack = new Stack<>();
int n1 = 10;
int n2 = 5;
stack.push(n1);
stack.push(n2);
System.out.println(new Main().add(stack.pop()));
}
} 

Output:

15

You might wonder what made the program return the sum of integer values instead of throwing an error. This is done by the compiler. It understands that the program requires to process of the addition of two numbers of Integer type. As it is not possible to add the values when passed to the function, it converts the values to the respective primitive types and returns the int value instead of an Integer object.

Advantages of java autoboxing and unboxing:

  • The presence of autoboxing and unboxing lets programmers write code in a clean manner that is easy to read.
  • The primitive types and wrapper class objects can be used without performing typecasting.

Sample program to list the primitive data types and their wrapper classes:

public class FirstCode{
public static void main(String args[]){
Integer obj = new Integer(10);
int dt = obj;
System.out.println(“Value of the object of Character class: ”+obj);
System.out.println(“Value of char data type:” + dt);
Character charobj = ‘a’;
char dt2 = obj2;
System.out.println(“Value of the object of Integer class: ”+dt2);
System.out.println(“Value of int data type:” + obj2);
}
}

Output:

Value of the object of Character class: 10
Value of char data type: 10
Value of the object of Integer class: a
Value of int data type: a

Sample program to implement the concept of Autoboxing and Unboxing in java:

import java.io.*;
class FirstCode{
public static void main(String args[]){
Integer i = new Integer(8);
int i2 = i;
System.out.println("Value of i:" + i);
System.out.println("Value of i2: " + i1);
Character fc= 'a';
char ch = fc
System.out.println("Value of ch: " + ch);
System.out.println(" Value of fc" + gfg);
}
}

Output:

Value of i: 8;
Value of i2: 8
Value of ch: a
Value of fc: a

Sample program to illustrate java autoboxing:

import java.io.*;
import java.util.*;
class FirstCode{
public static void main(String args[]){
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(5);
a.add(1);
a.add(2);
System.out.println(“ArrayList: ”+a);
}
}

Output:

ArrayList: [5, 1, 2]

Explanation of the output:

Here, we created a list of elements of Integer type. We add int primitive type values rather than Integer Object to make the code error-free during compilation. Due to this, the Java compiler creates an Integer wrapper Object from primitive int i adds it to the list.

Sample program to implement autoboxing in java:

import java.io.*;
import java.util.*;
class FirstCode{
public static void main(String args[]){
ArrayList<Integer> a = new ArrayList<Integer>();
for(int i = 0; i<5; i++){
System.out.println(list.add(Integer.valueOf(i)));
}
}

Output:

true
true
true
true
true

Example 4:

The below program finds the sum of even numbers in a list. What we must note here is that the operators remainder(%) and unary plus(+=) operators do not apply to Integer objects. Yet, the coding is successfully compiled as the Unboxing of the Integer Object to primitive value takes place. This process takes place by invoking the intValue() method at runtime.

import java.io.*;
import java.util.*;
class FirstCode{
public static int sumOfEvenNumbers(List<Integer> list){
int sum = 0;
for(Integer i : list){
if(2%==0)
sum = sum+i;
if(i.intValue()%2==0)
sum += i.intValue();
}
return sum;
}
public static void main(String args[]){
List<Integer> list = new ArrayList<Integer>();
for(int i=0; i<10; i++)
list.add(i);
int sumEven = sumOfEvenNumbers(list);
System.out.println(“Sum the even numbers below 10 are: ”+sumEven);
}
} 

Output:

20

Java Autoboxing and Unboxing with comparison operators:

Autoboxing is done using comparison operators. Here is a sample program to implement it:

class FirstCode{
public static void main(String args[]){
Integer i = new Ingeter(10);
if(i<20){    
//internal unboxing
System.out.println(i);
}
}
}

Java Autoboxing and Unboxing with function overloading:

Boxing and unboxing can take place in function overloading. The rules for method loading with boxing are:

1. Example of Autoboxing where widening beats boxing:

class FirstCode{
static void m(int i){System.put.println(“int”);} 
static void m(Integer i){System.put.println(“Integer”);}
public static void main(String args[]){
short s = 30;
m(s);
}
}

Output:

int

2. Example of Autoboxing in java where widening beats varargs:

class FirstCode{
static void m(int i, int i2){System.put.println(“int int”);} 
static void m(Integer… i){System.put.println(“Integer…”);}
public static void main(String args[]){
short s1 = 30, s2=40;
m(s1, s2);
}
}

Output:

int int

Example of Autoboxing where boxing beats varargs:

class FirstCode{
static void m(Integer i){System.put.println(“Integer”);} 
static void m(Integer… i){System.put.println(“Integer…”);}
public static void main(String args[]){
int s = 30;
m(s);
}
}

Output:

Integer

Method overloading with Widening and Boxing:

class FirstCode{
static void m(Long l){System.out.println(“Long”);}
public static void main(String args[]){
int a = 30;
m(a);
}
}

Output:

Compile Time Error

Points to note before using Autoboxing and Unboxing in Java:

To avoid complexities while using autoboxing and unboxing, we need to follow certain precautious methods.

1. Compare objects with equality operator:

The equality operator, ‘==,’ is error-prone when it is used as a primitive type and an object. To avoid confusion, it is better to use the equality operator with primitive types rather than objects. When it is used as an object, it is wiser to adopt the equals method.

2. Mix object and primitive type with equality:

Mixing the object with equality and relational operators is another issue. In instances where you need to compare a primitive type with an object, you can use the NullPointerException. This is effective when the object is null. Here is a sample program to give you an idea of how to execute it:

private static Integer num;
if(num <= 0){
System.out.println(“The number is invalid”);
}

3. Cached Objects:

The risk of a cached object can be avoided by using the valueOf() method. It created a boxed primitive type that can catch all the frequently used objects.

4. Unnecessary objects and GC overhead:

Implementing autoboxing creates an unwanted object that slows down the speed of the program by frequent garbage collection. These are the various problems one can face while using autoboxing and unboxing.

Conclusion:

Autoboxing and unboxing in Java are two tasks that the compiler takes care of. I hope this article gave you a clear idea of these concepts in simple means.

Leave a Reply

Your email address will not be published. Required fields are marked *