SCJP Study Guide:
API Contents


Printer-friendly version Printer-friendly version | Send this 
article to a friend Mail this to a friend


Previous Next vertical dots separating previous/next from contents/index/pdf Contents
XyzWs Study Guide: SCJP: Autoboxing

Autoboxing


Autoboxing, introduced in Java 5, is the automatic conversion the Java compiler makes between the primitive (basic) types and their corresponding object wrapper classes (eg, int and Integer, double and Double, etc). The underlying code that is generated is the same, but autoboxing provides a sugar coating that eliminates the need to explicitely create wrapper objects for primitive types.

Example


With Autoboxing Without Autoboxing

int i;
Integer j;
i = 1;
j = 2;
i = j;
j = i;

int i;
Integer j;
i = 1;
j = new Integer(2);
i = j.valueOf();
j = new Integer(i);


Boxing


Boxing conversion converts values of primitive type to corresponding values of reference type. Specifically, the following 8 conversion are called the boxing conversions:

  • From type boolean to type Boolean
  • From type byte to type Byte
  • From type char to type Character
  • From type short to type Short
  • From type int to type Integer
  • From type long to type Long
  • From type float to type Float
  • From type double to type Double

For example:


short s = 1;
int i = 1;
//Assignment conversion
Integer I1 = 1;
Integer I2 = i;
Integer I3 = s; //WRONG! Type mismatch, cannt convert from short to Integer
//Cast conversion
Integer I4 = (Integer)1;
Integer I5 = (Integer)i;
Integer I6 = (int)s;
Integer I7 = (Integer)s; //WRONG! Cannot cast from short to Integer

Normally, when the primitive types are boxed into the wrapper types, the JVM allocates memory and creates a new object. But for some special cases, the JVM reuses the same object.

The following is the list of primitives stored as immutable objects:

  • boolean values true and false
  • All byte values
  • short values between -128 and 127
  • int values between -128 and 127
  • char in the range \u0000 to \u007F

For example:

public class MyTestCode {
public static void main(String[] args) {
Integer i11 = new Integer(127);

Integer i21 = new
Integer(127);
System.out.println("i11 == i21 is " + (i11 == i21));

Integer j12 = 127;
Integer j22 = 127;
System.out.println("j12 == j22 is " + (j12 == j22));

Integer k11 = 128;
Integer k21 = 128;
System.out.println("k11 == k21 is " + (k11 == k21));

int k31 = 128;
System.out.println("k31 == k11 is " + (k31 == k11));

Integer l11 = -128;
Integer l21 = -128;
System.out.println("l11 == l21 is " + (l11 == l21));

Integer m11 = -129;
Integer m21 = -129;
System.out.println("m11 == m21 is " + (m11 == m21));

int m31 = -129;
System.out.println("m11 == m31 is " + (m11 == m31));

Character c11 = '\u0000';
Character c21 = '\u0000';
System.out.println("c11 == c21 is " + (c11 == c21));

Character c12 = '\u00FF';
Character c22 = '\u00FF';
System.out.println("c12 == c22 is " + (c12 == c22));

char c31 = 0xff;
System.out.println("c12 == c31 is " + (c12 == c31));

}
}

The output results are:

i11 == i21 is false
j12 == j22 is true
k11 == k21 is false
k31 == k11 is true
l11 == l21 is true
m11 == m21 is false
m11 == m31 is true
c11 == c21 is true
c12 == c22 is false
c12 == c31 is true

The == operator performs reference identity comparisons on Integer expressions and value equality comparisons on int expressions.

Unboxing

Unboxing conversion converts values of reference type to corresponding values of primitive type. Specifically, the following 8 conversion are called the unboxing conversions:

  • From type Boolean to type boolean
  • From type Byte to type byte
  • From type Character to type char
  • From type Short to type short
  • From type Integer to type int
  • From type Long to type long
  • From type Float to type float
  • From type Double to type double

For Example

Boolean boolRef = true;
Byte bRef = 50;
Short sRef = 2;
Character cRef = '1';
Integer iRef = 3;

//Unboxing
boolean bool = boolRef;
byte b = bRef;
short s = sRef;
char c = cRef;
int i = iRef;
short s1 = iRef; //WRONG! Type mismatch, cannot convert from Integer to short

An Integer expression can have a null value. If your program tries to autounbox null, it will throw a NullPointerException.

Integer i = null; int j = i; // java.lang.NullPointerException !!!

Example for comparison operators

public class TestCode {

public static void main(String[] args) {
Integer iVar1 = new Integer(100);
Integer iVar2 = 100;
System.out.println("Lessthan Check : " + (iVar1 <= iVar2));
System.out.println("Greater than Check : " + (iVar1 >= iVar2));
System.out.println("Equality Check : " + (iVar1 == iVar2));
}

}

The output results are

Lessthan Check : true
Greater than Check : true
Equality Check : false

When we are working with comparison operators, the boxing conversion works a little differently. The output for the above program shows that, The operators <, <=, >, and >= work fine. But when we come to the equals operator, ==, the JVM interprets that as the operator for object equality, rather than unboxing ivar2 and testing mathematical equality.

Prefer primitive types

Use the primitive types where there is no need for objects for two reasons.

  1. Primitive types may be a lot faster than the corresponding wrapper types, and are never slower.
  2. The immutability (can't be changed after creation) of the wrapper types may make it their use impossible.
  3. There can be some unexepected behavior involving == (compare references) and .equals() (compare values).

Method Invocation Conversion

The following rules is defined in the Java Specifiction:

Method invocation conversion is applied to each argument value in a method or constructor invocation (?8.8.7.1, ?15.9, ?15.12): the type of the argument expression must be converted to the type of the corresponding parameter. Method invocation contexts allow the use of one of the following:

  • an identity conversion (?5.1.1)
  • a widening primitive conversion (?5.1.2)
  • a widening reference conversion (?5.1.5)
  • a boxing conversion (?5.1.7) optionally followed by widening reference conversion
  • an unboxing conversion (?5.1.8) optionally followed by a widening primitive conversion.

The general rule is, for compatibility reasons, the same behavior that applied in pre-5.0 versions must continue to hold. The reason is that existing code cannot suddenly start behaving differently when compiled and run under 5.0. 

 


Previous Next vertical dots separating previous/next from contents/index/pdf Contents

  |   |