Algorithms and OOD (CSC 207 2014F) : Readings
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [Learning Outcomes] [FAQ] [Teaching & Learning] [Grading] [Rubric] - [Calendar]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Readings]
Reference: [Student-Curated Resources] [Java 8 API] [Java 8 Tutorials] [Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2014S (Rebelsky)] [CSC 207 2014F (Walker)] [CSC 207 2011S (Weinman)]
Misc: [Submit Questions] - [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)] [Issue Tracker (Textbook)]
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.
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 - int
s were
int
s and Integer
s were Integer
s.
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.
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.
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.
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 |
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 Integer
s,
but not int
s. In contrast, you really only use
int
s 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.
What should you take away from this reading? A few things.
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.