JavaRush /Java Blog /Random EN /Autoboxing and unboxing in Java
DSergey_Kh
Level 12

Autoboxing and unboxing in Java

Published in the Random EN group
In this article we will look at a feature in Java called autoboxing/unboxing . Autoboxing and unboxing is a function of converting primitive types to object types and vice versa. Autoboxing and unboxing in Java - 1The entire process is performed automatically by the Java Runtime Environment (JRE). But you should be careful when implementing this function, because... It can affect the performance of your program.

Introduction

In versions below JDK 1.5, it was not easy to convert primitive data types such as int, char, float, doubleto their wrapper classes Integer, Character, Float, Double. Starting with JDK 5, this functionality, converting primitive types to equivalent objects, is implemented automatically. This property is known as Autoboxing . The reverse process, respectively, is Unboxing , i.e. the process of converting objects into their corresponding primitive types. Sample code for autoboxing and unboxing is given below: Autoboxing
Integer integer = 9;
Unboxing
int in = 0;
in = new Integer(9);
When is auto packing and unpacking used? Autoboxing is used by the Java compiler under the following conditions:
  • When a value of a primitive type is passed to a method as a method parameter, which expects an object of the corresponding wrapper class.
  • When a value of a primitive type is assigned to a variable of the corresponding wrapper class.
Consider the following example: Listing 1: Simple code showing autoboxing
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
Prior to jdk 1.5, the above code would have caused a compilation error because the remainder operator % and unary plus += could not be applied to a wrapper class. But in jdk 1.5 and above this code compiles without errors, converting Integer to int. Unboxing is used by the Java compiler under the following conditions:
  • When an object is passed as a parameter to a method that expects a corresponding primitive type.
  • When an object is assigned to a variable of the corresponding primitive type.
Consider the following example: Listing 2: Simple code showing unboxing
import java.util.ArrayList;
import java.util.List;

public class UnboxingCheck {

public static void main(String[] args) {
Integer in = new Integer(-8);

// 1. Распаковка через вызов метода
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);

List<Double> doubleList = new ArrayList<Double>();

// Автоупаковка через вызов метода
doubleList.add(3.1416);

// 2. Распаковка через присвоение
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}

public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
Autoboxing and unboxing allows the developer to write code that is easy to read and understand. The following table shows the primitive data types and their corresponding wrapper objects.
Primitive types Shell classes
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
Table 1: Primitive types and equivalent wrapper classes with comparison operators Autoboxing and unboxing can be used with comparison operators. The following code snippet illustrates how this happens: Listing 3: Sample code showing autoboxing and unboxing with a comparison operator
public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}
Autopacking and unpacking when overloading a method Autopacking and unpacking is performed when overloading a method based on the following rules:
  • Expansion “defeats” packaging in a situation where there is a choice between expansion and packaging; expansion is preferable.
Listing 4: Sample code showing the benefit of overloading
public class WideBoxed {
  public class WideBoxed {
  static void methodWide(int i) {
       System.out.println("int");
   }

  static void methodWide( Integer i ) {
      System.out.println("Integer");
  }

  public static void main(String[] args) {
      short shVal = 25;
      methodWide(shVal);
  }
 }
}
Program output - typeint
  • Expansion beats variable number of arguments In a situation where it becomes a choice between expansion and variable number of arguments, expansion is preferable.
Listing 5: Sample code showing the benefit of overloading
public class WideVarArgs {

    static void methodWideVar(int i1, int i2) {
      System.out.println("int int");
    }

    static void methodWideVar(Integer... i) {
       System.out.println("Integers");
    }

   public static void main( String[] args) {
       short shVal1 = 25;
      short shVal2 = 35;
     methodWideVar( shVal1, shVal2);
   }
  }
  • Packing beats variable number of arguments In a situation where it becomes a choice between packing and variable number of arguments, packing is preferable.
Listing 6: Sample code showing the benefit of overloading
public class BoxVarargs {
     static void methodBoxVar(Integer in) {
         System.out.println("Integer");
     }

     static void methodBoxVar(Integer... i) {
         System.out.println("Integers");
     }
     public static void main(String[] args) {
         int intVal1 = 25;
         methodBoxVar(intVal1);
    }
}
You should keep the following things in mind while using Auto Packing: As we know, every good feature has a drawback. Auto packaging is no exception in this regard. Some important notes that a developer should keep in mind when using this feature:
  • Comparing objects with the ' ==' operator can be confusing, since it can be applied to primitive types and objects. When this operator is applied to objects, it actually compares references to the objects, not the objects themselves.
Listing 7: Sample code showing the comparison.
public class Comparator {
   public static void main(String[] args) {
     Integer istInt = new Integer(1);
       Integer secondInt = new Integer(1);

       if (istInt == secondInt) {
         System.out.println("both one are equal");

       } else {
          System.out.println("Both one are not equal");
      }
   }
}
  • Mixing objects and primitive types with the equality and relational operators. If we compare a primitive type with an object, then the object is unboxed, which can throw NullPointerExceptionif the object null.
  • Object caching. The method valueOf()creates a container of primitive objects that it caches. Because values ​​are cached in the range -128 to 127, inclusive, these cached objects may behave differently.
  • Performance degradation. Autoboxing or unboxing degrades application performance because it creates an unwanted object that forces the garbage collector to run more frequently.
Disadvantages of AutoBoxing Although AutoBoxing has a number of advantages, it has the following disadvantages: Listing 8: Sample code showing the performance issue.
public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }
In this section of code, sum +=i it will be expanded to sum = sum + i. Starting with the ' +' operator, the JVM starts unboxing because the ' +' operator cannot be applied to an Integer object. And then the result is autopacked back. Before JDK 1.5, data types intand Integer were different. In case of method overloading, these two types were used without problems. With the advent of automatic packing/unpacking, this has become more difficult. An example of this is the overloaded method remove()in ArrayList. The class ArrayListhas two delete methods - remove(index)and remove(object). In this case, method overloading will not occur and the corresponding method will be called with the appropriate parameters.

Conclusion

Autoboxing is a mechanism for implicitly converting primitive data types into corresponding wrapper classes (objects). The compiler uses the method valueOf()to convert primitive types into objects, and the methods IntValue(), doubleValue()etc., to obtain the primitive types of the object. Autoboxing converts boolean type booleanto Boolean, byteto Byte, charto Character, floatto Float, intto Integer, longto Long, shortto Short. Unpacking occurs in the reverse direction. Original article
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION