Friday, February 25, 2011

Primitive types vs. Boxed Primitives

Java has primitive types like int, short, float, double etc... and reference types like String, Collection etc... Each of the primitive types also has a equivalent reference type. int has Integer, long has Long and so on. These reference types are called Boxed primitives.

Primitive types vs. Boxed Primitives
Primitive Types
Boxed Primitives
Support only functional values (1, 4.5 etc...)
Supports functional values and null
Time and space efficient
Less time and space efficient than primitive types
Have only values. 4 == 4.
Have values and an identity. new Integer(4) != new Integer(4). So avoid using == on boxed primitives

Consider the following code:

public class Test
{
    Integer i; // Initialized to null
    public static void main(String[] args)
    {
        if ( i == 45 ) // 1. auto-unbox i (convert Integer to int) 2. NullPointerException as i value is null.
        {
            System.out.println( "i is 45." );
        }
    }
}

In the above example, i is initialized to null (since its a instance variable). Subsequently, when i == 45 is encountered, i is first auto un-boxed (converted from Integer to int) and this conversion fails because i is null. Fix this by declaring i as int (instead of Integer).

Moral of the story:
Prefer using primitives over boxed types. If using boxed types follow these:
1. Must not be using == operator with boxed types (none of the operands to == must be a boxed type). If used,
a. References are compared, not values and hence results will (in most cases) be wrong.
b. If one operand is primitive and other is boxed primitive, then the boxed primitive is un-boxed. This un-boxing could throw a NullPointerException.
2.
If using boxed types with other operator (like +=), consider overhead involved in auto-boxing and un-boxing. Integer i = 10; i += 2; // un-box value of i, add 2 to unboxed value and box the result back into i. Not efficient.

Use Boxed primitives when:
1. Using parameterized types (list Collection).
Parameterized types do not permit primitives.
2. Using value as a key or value in Collections.
3. Using reflective method invocation (another don't do). e.g. class.forName("java.lang.Integer");

Source: Effective Java by Joshua Bloch

4 comments:

Sameera Nelson said...
This comment has been removed by the author.
Sameera Nelson said...
This comment has been removed by the author.
Sameera Nelson said...

This article written by me describe more facts on immutability,

http://www.devdummy.com/2017/09/immutable-objects-in-java.html

Thanks.

bhushan rathi said...

was reading effective java and googled this statement, and found this
very well explained,
thank you