Thursday, April 12, 2012

Autoboxing,Autounboxing and Overloading in Java

Introduction

Auto-boxing and AutoUnboxing is the new feature added in Java 5 where java compiler automatically converts the primitive(basic) data types into corresponding object wrapper classes and vice versa.

Autoboxing example:-
Prior to Java 5,if we have to add int/long/double/.... primitives into any collection classes,we have to explicitly convert them into corresponding Number wrapper classes and add them into collection.However with the advent of Java 5,we need not have to explicitly do the same.It happens automatically as compiler generates the code which converts primitive to wrapper classes and vice versa.

Code prior to Java 5
int data1=29;
int data2=30;
long data3=56;
float data4=12.3f;

List dataList=new ArrayList();
dataList.add(new Integer(data1));
dataList.add(new Long(data2));
dataList.add(new Float(data3));

Code as per Java 5
int data1=29;
int data2=30;
long data3=56;
float data4=12.3f;

List dataList=new ArrayList();
dataList.add(data1);
dataList.add(data2);
dataList.add(data3);

So in Java 5,we need not have to convert the primitive data types into Number wrapper classes.Its taken by the compiler which handle it seamlessly

Autounboxing example:-
Prior to Java 5 if we have to do any increment/decrement of the wrapper object.We have to get the primitive value from the wrapper number object ,increment/decrement the same and push it back to wrapper object.

Code prior to Java5
Integer intData=new Integer(10);
int primitiveVal=intData.intValue();
primitiveVal++;
intData=new Integer(primitiveVal);

Long longData=new Long(20);
long primVal=longData.longValue();
primVal++;
longData=new Long(primVal);

Code as per Java5
Integer intData=new Integer(10);
intData++;

Long longData=new Long(20);
longData++;

So in Java5,we need not have to convert wrapper objects into primitives for increment/decrement operations.


Overloading and auto boxing/unboxing

So how does auto boxing/unboxing affects overloading.It follows following principles.These are:-
i)First it tries to find the method matching the exact data type.
ii)In case of wrapper classes,if it does not find any method as per step -1.It tries to find the method matching the corresponding primitive data type.
iii)If it does not find any method corresponding to step-2.Then it tries to find the method matching the widen primitive data type.

i.e
If in a class we have overloaded method display taking byte/long as parameters and we invoke display method with Integer as parameter.It will invoke display method having long as parameter

Inorder to understand better lets go through some examples.

Example-1:-
In this example we have overloaded methods taking Integer object and primitive int.So when we invoke this for int or Integer object ,it invokes the corresponding method



package com.kunaal.overloading;

/**
 * 
 * @author KunaalATrehan
 *
 */
public class BasicOverLoadingTest {

 /**
  * Overloaded display method taking primitive integer
  * @param i
  */
 private void display(int i){
  System.out.println("Primitive method invoked,data is -"+ i);
 }
 
 /**
  * Overloaded display method taking integer number wrapper class
  * @param i
  */
 private void display(Integer i){
  System.out.println("Number wrapper method invoked,data is-"+ i);
 }
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  BasicOverLoadingTest dataObj=new BasicOverLoadingTest();
  dataObj.display(10);
  dataObj.display(new Integer(789));
 }

}

Output

Primitive method invoked,data is -10
Number wrapper method invoked,data is-789

Example 2:-


In this example we will test the rule -2.We have overloaded methods taking int and long primitive data type.Then we invoke the overloaded method for Long wrapper class.So when we invoke the overloaded method for Long data type,invokes the overloaded method which has primitive long as parameter.


package com.kunaal.overloading;

/**
 * @author KunaalATrehan
 *
 */
public class ShortenOverloadingTest {
 
 /**
  * Overloaded display method taking primitive int as parameter
  * 
  * @param i
  */
 private void display(int i){
  System.out.println("Display invoked for primitive int,data is :-"+ i);
 }
 
 /**
  * Overloaded display method taking primitive long as parameter
  * @param i
  */
 private void display(long i){
  System.out.println("Display invoked for primitive long,data is :-"+ i);
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  ShortenOverloadingTest dataObj=new ShortenOverloadingTest();
  dataObj.display(10);
  dataObj.display(new Long(100));
 }

}


Output


Display invoked for primitive int,data is :-10
Display invoked for primitive long,data is :-100

Example 3:-

In this example we will test the rule-3.We have overloaded methods taking primitive byte,int,float and Integer wrapper.When we invoke the method for Long wrapper parameter,it invokes the method having float as parameter.Since there is no matching method for Long wrapper class.It searches for method having long primitive data type.Since there is no such method available,it finds a method which can take parameter bigger than long primitive data type which in this case is float.So it invokes the same for Long wrapper object.


package com.kunaal.overloading;

/**
 * @author KunaalATrehan
 *
 */
public class OverloadingTest {

 /**
  * Overloaded method for primitive byte
  * @param i
  */
 private void display(byte i){
  System.out.println("Display invoked for primitive byte,data is -"+ i);
 }

 /**
  * Overloaded method for primitive int
  * @param i
  */
 private void display(int i){
  System.out.println("Display invoked for primitive int,data is -"+ i);
 }
 
 /**
  * Overloaded method for primitive float
  * @param i
  */
 private void display(float i){
  System.out.println("Display invoked for primitive float,data is-"+ i);
 }
 
 /**
  * Overloaded method for Integer wrapper object
  * @param i
  */
 private void display(Integer i){
  System.out.println("Display invoked for Integer wrapper,data is-"+ i);
 }
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  OverloadingTest dataObj=new OverloadingTest();
  byte data=32;
  dataObj.display(data);
  dataObj.display(30);
  dataObj.display(new Long(909090));
  dataObj.display(null);
 }

}

Output


Display invoked for primitive byte,data is -32
Display invoked for primitive int,data is -30
Display invoked for primitive float,data is-909090.0
Display invoked for Integer wrapper,data is-null

2 comments:

  1. Very Good Article about overloading. It helps to understanding overloading in depth. Thanks dude for this article.

    ReplyDelete