Algorithms and OOD (CSC 207 2014F) : Readings

Automatic Boxing and Unboxing in Java


Summary: We consider some of the ways in which Java converts from primitive values to object values (boxing) and from object values back to primitive values (unboxing).

Prerequisites: Java basics.

Introduction

As we note in the reading on reference values, Java has two “kinds” of values, primitive values and object values. You may have noted that for each primitive type, we have a corresponding object type: for int values, we have Integer objects, for double values, we have Double objects, and so on and so forth.

Early versions of Java required programmers to carefully distinguish which kind of value you were using - ints were ints and Integers were Integers. The process of converting from primitive type to corresponding object is called boxing. The process of converting from object to primitive type is called unboxing. In Java, we typically call a constructor to box a value, and we call an observer to unbox a value.

Starting in Java 1.5 (also called Java 5.0), the Java compiler started doing automatic boxing (also called “autoboxing”) and automatic unboxing (also called “autounboxing”).

Let's consider some of the implications of manual and automatic boxing and unboxing.

Manual Boxing

What does it mean that a programmer has to manually box and unbox values? Let's consider a few simple examples. First, if you wanted to assign an int to an Integer, you'd have to call a constructor.

  int prim = 5;
  Integer obj = new Integer(prim);   

Similarly, if you wanted to assign an Integer to an int, you'd have to extract its value.

  prim = obj.intValue();

The different treatment also meant that we had to extract the int value from an Integer before doing math on it, and then package it back up again.

  prim++;
  obj = new Integer(obj.intValue() + 1);

Note that we could not write the following. Can you tell why not?

  obj = new Integer((obj.intValue())++);

To recap: Early versions of Java asked programmers to think carefully about when they were using a primitive value and when they were using an object value. These versions also required programmers to explicitly convert between the forms.

Automatic Boxing and Unboxing

What does it mean that both boxing and unboxing are “automatic”? It means that we no longer need to explicitly convert from primitive value to boxed object or back again - the Java compiler does the conversion for us.

Hence, we can write all of the above (including that one postincrement that seemed impossible before).

  int prim = 5;
  Integer obj = prim;
  prim = obj;
  obj = obj * obj;
  obj++;
  prim++;
 

However, note that behind the scenes, the Java compiler is probably generating code similar to that you had to manually write before.

Boxed Types

What primitive types get automatically boxed and unboxed? Here's the basic list. Note that all of the boxed classes are in the package java.lang.

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

Benefits and Drawbacks of Automatic Boxing

Why did the designers of Java add automatic boxing? There are a few reasons. One obvious reason is that it makes things much easier for the programmer. No longer do you have to worry about whether you have a primitive value or a boxed value - you can write identical code for the two.

Why did it take so long for automatic boxing and unboxing to appear in Java? Because many people were concerned that conversion between types is costly, and programmers should know the cost of the operations they do. For example, consider how much effort the computer needs to do to compute the following assignment statement.

  i = i + j;

The answer is now “it depends”. If both i and j hold primitive values, the assignment statement can probably be translated into one machine-language instruction. (Well, it may need a few more for fetching and storing data, but it's still pretty close to one.)

In contrast, if both i and j hold boxed values, we probably need to to follow references to the corresponding objects, extract the value from each object, do the operation, and build a new object. These operations are likely to be much slower. (On a pipelined architecture, having to follow references is often particularly painful.)

By introducing autoboxing and unboxing, Java designers have made it easier for programmers to write inefficient code without realizing quite how inefficient the code is.

Given that significant drawback, why did the designers add this feature? Because Java 1.5 introduced generics and a whole set of collections classes that can only hold objects. For example, you can make an ArrayList that contains Integers, but not ints. In contrast, you really only use ints in for loops. Autoboxing allows us to more easily write things like

  ArrayList<Integer> values = new ArrayList<Integer>();
  for (int i = 0; i < 100; i++)
    {
      values.add(i);
    } // for

and

  int sum = 0;
  for (Integer val : values) 
    {
      sum += val;
    } // for

These patterns of programming are common enough that it must have seemed worthwhile to allow programmers to type a bit less, even if it means they may also think a bit less about the efficiency of their code.

Are there other potential problems with automatic boxing and unboxing? Some programmers note that boxed types have one additional value not representable as primitive types. That is, objects can be null and primitive values cannot. What happens when you try to unbox null? You'll figure that out in the lab.

Things to Remember

What should you take away from this reading? A few things.

  • For the important primitive types, there's a corresponding class.
  • Java allows you to treat primitive and object values as the same thing (more or less).
  • You should think carefully about what representation you use. When you use object values, you may be incurring hidden performance penalty.

References

Oracle (1995,2014). Autoboxing and Unboxing. The Java Tutorials. Online document at http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html. Last visited 2014-02-09.

Keefer, Alan (2008). Why I'm Not a Fan Of Java's Auto-Unboxing. DZone Javalobby. Online document at http://java.dzone.com/articles/why-im-not-a-fan-of-javas-auto. Dated 07.09.2008. Last visited 2014-02-09.