Sunday, 1 April 2012

Wrapper classes in Java

Java is not a pure object oriented langauage, Why?.The Java primitive types (byte,short,int,long,float,double,char,boolean) are implemented without using OOP's concepts.They cannot participate in the object activities, such as being used for calling methods, being returned from a method as an object, and being added to a Collection of objects, etc. As a solution to this problem, Java allows you to include the primitives in the family of objects by using what are called wrapper classes.Each of Java's eight primitive data types has a class dedicated to it.They "wrap" the primitive data type into an object of that class. So, there is an Integer class that holds an int variable, there is a Double class that holds a double variable, and so on. The wrapper classes are part of the java.lang package, which is imported by default into all Java programs.

Following table lists the primitive types and the corresponding wrapper classes and corresponding base classes.

Primitive
Wrapper
Base Class
boolean
java.lang.Boolean
Java.lang.Object
byte
java.lang.Byte
Java.lang.Number
char
java.lang.Character
Java.lang.Object
double
java.lang.Double
Java.lang.Number
float
java.lang.Float
Java.lang.Number
int
java.lang.Integer
Java.lang.Number
long
java.lang.Long
Java.lang.Number
short
java.lang.Short
Java.lang.Number
void
java.lang.Void
Java.lang.Object


Reasons for using Wrapper Class

  1. As an argument of a method that expects an object (often used when manipulating collections of numbers).
  2. The wrapped primitives can be included in activities reserved for objects, like as being added to Collections, or returned from a method with an object return value.
  3. To use constants defined by the class, such as MIN_VALUE and MAX_VALUE, that provide the upper and lower bounds of the data type.
  4. To use wrapper utility methods for converting values to and from other primitive types, for converting to and from strings, and for converting between number systems (decimal, octal, hexadecimal, binary).

Creating the Wrapper Object

The wrapper objects can be created in three different ways as given below
  1. Using wrapper classes offered Constructors
  2. Using wrapper classes offered static valueOf() methods
  3. Using Autoboxing feature available since java 1.5.
We will explore this further in this article.

1)Wrapping Primitives Using Wrapper Classes Offered   Constructors.


Following table lists the wrapper classes and corresponding constructors.



Wrapper
Constructors
Byte
Byte(byte value)
Byte(String s)
Short
Short(short value)
Short(String s)
Integer
Integer(int value)
Integer(String s)
Long
Long(long value)
Long(String s)
Float
Float(float value)
Float(double value)
Float(String s)
Double
Double(double value)
Double(String value)
Character
Character(char c)
Boolean
Boolean(boolean b)
Boolean(String s)
Void
None


For example:
        Byte b1 = new Byte((byte) 1);
        Byte b2 = new Byte("1");


        Short s1 = new Short((short) 100);
        Short s2 = new Short("100");


        Integer i1 = new Integer(10);
        Integer i2 = new Integer("10");


        Long l1 = new Long(1000);
        Long l2 = new Long("1000");


        Float f1 = new Float(3.14);
        Float f2 = new Float("3.14");


        Double d1 = new Double(3.14);
        Double d2 = new Double("3.14");


        Boolean bool1 = new Boolean(true);
        Boolean bool2 = new Boolean("true");
   
        Character c1 = new Character('A');


2) Wrapping Primitives Using valueOf() static Method


All wrapper classes offers valueOf() static methods for creating wrapper objects.The following table lists the wrapper classes and the corresponding valueOf() methods.

 

Wrapper
Static valueOf() method
Byte
valueOf(byte value)
valueOf(String s)
valueOf(String s,int radix)
Short
valueOf(short value)
valueOf(String s)
valueOf(String s,int radix)
Integer
valueOf(int value)
valueOf(String s)
valueOf(String s,int radix)
Long
valueOf(long value)
valueOf(String s)
valueOf(String s,int radix)
Float
valueOf(float value)
valueOf(String s)
Double
valueOf(double value)
valueOf(String value)
Character
valueOf(char c)
Boolean
valueOf(boolean b)
valueOf(String s)
Void
None
 

For example

        Byte b1 = Byte.valueOf((byte) 10);
        Byte b2 = Byte.valueOf("10");
        Byte b3 = Byte.valueOf("10", 2);

        Short s1 = Short.valueOf((short) 10);
        Short s2 = Short.valueOf("10");
        Short s3 = Short.valueOf("10", 8);

        Integer i1 = Integer.valueOf(10);
        Integer i2 = Integer.valueOf("10");
        Integer i3 = Integer.valueOf("10", 16);

        Long l1 = Long.valueOf(10);
        Long l2 = Long.valueOf("10");
        Long l3 = Long.valueOf("10", 16);

        Float f1 = Float.valueOf(3.14f);
        Float f2 = Float.valueOf("3.14");

        Double d1 = Double.valueOf(3.14);
        Double d2 = Double.valueOf("3.14");

        Boolean bool1 = Boolean.valueOf(true);
        Boolean bool2 = Boolean.valueOf("true");
       
        Character c1 = Character.valueOf('a');    


Notice that Byte,Short ,Integer and Long valueOf() methods take an additional argument, int radix, which indicates in what base (for example binary, octal, or hexadecimal) the first argument is represented.
for example,
        Integer i1 = Integer.valueOf("1001",2);
Here converts 1001 to 9 and assigns the value 9 to the  Integer object i2.

Why YOU should use static valueOf() method


Wrapper objects are immutable same as String object in java.That means once created we can't change the value of a wrapper object.In order to improve the space and time performance while manipulating with strings, java implements String Constant Pool for String objects.Similarly Java 5 implements caching of frequently requested wrapper objects.

 

The following wrapper objects support cashing

Byte 

Short from -128 to 127

Character from \u0000 to \u007f

Integer from -128 to 127

Long from -128 to 127

Boolean

 

We will discuss the cashing with an example

Integer i1=new Integer(10);
Integer i2=new Integer(10);
System.out.println("i1 memory==i2 memory "+(i1==i2));

Integer i3=Integer.valueOf(100);
Integer i4=Integer.valueOf(100);
System.out.println("i3 memory==i4 memory "+(i3==i4));

You will get the output

i1 memory ==i2 memory  false
i3 memory ==i4 memory  true
 

Notice that i1 and i2 are stored in different memory location.When using new operator for wrapper object creation, individual objects are constructed for i1 and i2 even if both contains same value 10.But the objects i3 and i4 constructed with valueOf() method are stored in same memory location.Because when creating i3 with value 100, caches Integer object 100 and can hand you back the same exact Integer object 100 every time instead of wasting an object construction on a brand new identical Integer object.

If a new Integer instance is not required, Integer.valueOf() method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values.


3) Wrapping Primitives Using Autoboxing feature introduced in Java 1.5


Java 5  and above supports automatic conversion of primitive types (int, float, double etc.) to their object equivalents (Integer, Float, Double,...) in assignments and method and constructor invocations. This conversion is know as autoboxing.   

For example

public class Main {

public static void main(String args[]) {

Integer i1 = 10;

add(10, 20);
}

static void add(Integer a, Integer b) {
}

}

Autoboxing is implemented using static valueOf() methods available in wrapper classes.So autoboxing also supports above mentioned feature,caching of wrapper objects.

Please visit Autoboxing and Unboxing in Java to learn more about this feature.

No comments:

Post a Comment