Chapter: Java The Complete Reference - The Java Language - Enumerations, Autoboxing, and Annotations (Metadata)

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Autoboxing - Java

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.

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.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.