Autoboxing
Beginning with JDK 5, Java
added two important features: autoboxing
and auto-unboxing. Autoboxing is the
process by which a primitive type is automatically encapsulated (boxed) into
its equivalent type wrapper whenever an object of that type is needed. There is
no need to explicitly construct an object. Auto-unboxing is the process by
which the value of a boxed object is automatically extracted (unboxed) from a
type wrapper when its value
is needed. There is no need
to call a method such as intValue( )
or doubleValue( ). The addition of
autoboxing and auto-unboxing greatly streamlines the coding of
several algorithms, removing
the tedium of manually boxing and unboxing values. It also helps prevent
errors. Moreover, it is very important to generics, which operate only on
objects. Finally, autoboxing makes working with the Collections Framework
(described in Part II) much easier.
With autoboxing, it is no
longer necessary to manually construct an object in order to wrap a primitive
type. You need only assign that value to a type-wrapper reference. Java
automatically constructs the object for you. For example, here is the modern
way to construct an Integer object
that has the value 100:
Integer iOb = 100; // autobox an int
Notice that the object is not
explicitly created through the use of new.
Java handles this for you, automatically.
To unbox an object, simply
assign that object reference to a primitive-type variable. For example, to
unbox iOb, you can use this line:
int i = iOb; // auto-unbox
Java handles the details for
you.
Here is the preceding program
rewritten to use autoboxing/unboxing:
// Demonstrate autoboxing/unboxing.
class AutoBox {
public static void main(String args[]) {
Integer iOb = 100; // autobox an int
int i = iOb; // auto-unbox
System.out.println(i + " " + iOb); //
displays 100 100
}
}
Autoboxing
and Methods
In addition to the simple
case of assignments, autoboxing automatically occurs whenever a primitive type
must be converted into an object; auto-unboxing takes place whenever an object
must be converted into a primitive type. Thus, autoboxing/unboxing might occur
when an argument is passed to a method, or when a value is returned by a
method. For example, consider this:
Autoboxing/unboxing takes place with
method parameters and return values.
class AutoBox2 {
Take an Integer parameter and return
an int value;
static int m(Integer v) {
return v ; // auto-unbox to int
}
public static void main(String args[]) {
Pass an int to m() and assign the return value
to an Integer.
Here, the argument 100 is autoboxed
into an Integer. The return value is also autoboxed
into an Integer.
Integer iOb = m(100);
System.out.println(iOb);
}
}
This program displays the
following result:
In the program, notice that m( ) specifies an Integer parameter and returns an int result. Inside main( ),
m( ) is passed the value 100.
Because m( ) is expecting an Integer, this value is automatically
boxed. Then, m( ) returns the int equivalent of its argument. This
causes v to be auto-unboxed. Next,
this int value is assigned to iOb in main( ), which causes the int
return value to be autoboxed.
Autoboxing/Unboxing
Occurs in Expressions
In general, autoboxing and
unboxing take place whenever a conversion into an object or from an object is
required. This applies to expressions. Within an expression, a numeric object
is automatically unboxed. The outcome of the expression is reboxed, if
necessary. For example, consider the following program:
// Autoboxing/unboxing occurs inside
expressions.
class AutoBox3 {
public static void main(String args[]) {
Integer iOb, iOb2; int i;
iOb = 100;
System.out.println("Original value of iOb:
" + iOb);
//The following automatically unboxes iOb, performs
the increment, and then reboxes the result back into iOb.
++iOb;
System.out.println("After ++iOb: " +
iOb);
Here, iOb is unboxed, the expression is
evaluated, and the result is reboxed and
assigned to iOb2.
iOb2 = iOb + (iOb / 3);
System.out.println("iOb2 after expression:
" + iOb2);
The same expression is evaluated, but the
result is not reboxed.
i = iOb + (iOb / 3);
System.out.println("i after expression:
" + i);
}
}
The output is shown here:
Original value of iOb: 100 After ++iOb: 101
iOb2 after expression: 134 i after expression:
134
In the program, pay special
attention to this line:
++iOb;
This causes the value in iOb to be incremented. It works like
this: iOb is unboxed, the value is
incremented, and the result is reboxed.
Auto-unboxing also allows you
to mix different types of numeric objects in an expression. Once the values are
unboxed, the standard type promotions and conversions are applied. For example,
the following program is perfectly valid:
class AutoBox4 {
public static void main(String args[]) {
Integer iOb = 100;
Double dOb = 98.6;
dOb = dOb + iOb;
System.out.println("dOb after expression:
" + dOb);
}
}
The output is shown here:
dOb after expression: 198.6
As you can see, both the Double object dOb and the Integer
object iOb participated in the
addition, and the result was reboxed and stored in dOb.
Because of auto-unboxing, you
can use Integer numeric objects to
control a switch statement. For
example, consider this fragment:
Integer iOb = 2;
switch(iOb) {
case 1: System.out.println("one");
break;
case 2: System.out.println("two");
break;
default: System.out.println("error");
}
When the switch expression is evaluated, iOb is unboxed and its int
value is obtained.
As the examples in the
program show, because of autoboxing/unboxing, using numeric objects in an
expression is both intuitive and easy. In the past, such code would have
involved casts and calls to methods such as intValue( ).
Autoboxing/Unboxing
Boolean and Character Values
As described earlier, Java
also supplies wrappers for boolean
and char. These are Boolean and Character. Autoboxing/unboxing applies to these wrappers, too. For
example, consider the following program:
// Autoboxing/unboxing a Boolean and Character.
class AutoBox5 {
public static void main(String args[]) {
Autobox/unbox a boolean. Boolean b = true;
Below, b is auto-unboxed when used in
a conditional expression, such as an if.
if(b) System.out.println("b is
true");
Autobox/unbox a char.
Character ch = 'x'; // box a char
char ch2 = ch; // unbox a char
System.out.println("ch2 is " + ch2);
}
}
The output is shown here:
b is true
ch2 is x
The most important thing to
notice about this program is the auto-unboxing of b inside the if
conditional expression. As you should recall, the conditional expression that
controls an if must evaluate to type
boolean. Because of auto-unboxing,
the boolean value contained within b is automatically unboxed when the
conditional expression is evaluated. Thus, with the advent of
autoboxing/unboxing, a Boolean
object can be used to control an if
statement.
Because of auto-unboxing, a Boolean object can now also be used to
control any of Java’s loop statements. When a Boolean is used as the conditional expression of a while, for, or do/while, it is
automatically unboxed into its boolean
equivalent. For example, this is now perfectly valid code:
Boolean b;
// ...
while(b) { // ...
Autoboxing/Unboxing
Helps Prevent Errors
In addition to the
convenience that it offers, autoboxing/unboxing can also help prevent errors.
For example, consider the following program:
// An error produced by manual unboxing.
class UnboxingError {
public static void main(String args[]) {
Integer iOb = 1000; // autobox the value 1000
int i = iOb.byteValue(); // manually unbox as
byte !!!
System.out.println(i); // does
not display 1000 !
}
}
This program displays not the
expected value of 1000, but –24! The reason is that the value inside iOb is manually unboxed by calling byteValue( ), which causes the
truncation of the value stored in iOb,
which is 1,000. This results in the garbage value of –24 being assigned to i. Auto-unboxing prevents this type of
error because the value in iOb will
always auto-unbox into a value compatible with int.
In general, because
autoboxing always creates the proper object, and auto-unboxing always produces
the proper value, there is no way for the process to produce the wrong type of
object or value. In the rare instances where you want a type different than
that produced by the automated process, you can still manually box and unbox
values. Of course, the benefits of autoboxing/unboxing are lost. In general,
new code should employ autoboxing/unboxing. It is the way that modern Java code
is written.
A
Word of Warning
Because of autoboxing and
auto-unboxing, some might be tempted to use objects such as Integer or Double exclusively, abandoning primitives altogether. For example,
with autoboxing/unboxing it is possible to write code like this:
// A bad use of autoboxing/unboxing!
Double a, b, c;
a = 10.0; b = 4.0;
c = Math.sqrt(a*a + b*b);
System.out.println("Hypotenuse is " +
c);
In this example, objects of
type Double hold values that are
used to calculate the hypotenuse of a right triangle. Although this code is
technically correct and does, in fact, work properly, it is a very bad use of
autoboxing/unboxing. It is far less efficient than the equivalent code written
using the primitive type double. The
reason is that each autobox and auto-unbox adds overhead that is not present if
the primitive type is used.
In general, you should
restrict your use of the type wrappers to only those cases in which an object
representation of a primitive type is required. Autoboxing/unboxing was not
added to Java as a “back door” way of eliminating the primitive types.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.