Google

Friday, May 11, 2007

Method Overloading with new features of Java 1.5

I was playing with Autoboxing and Ver-args features of Java 1.5 and found interesting results with method overloading.

If you have a class which has a method void hello(Integer x) and you call hello(5) then Autoboxing will come into play may and method hello will be called.

Another case is, If you have a method void hello(long x) and you call
hello(5) then primitive integer 5 will be widened to long and method hello will be called.

Now suppose you have hello method overloaded in your class. Lets look at this example in detail.

public class methodOverloading{
public static void hello(Integer x){System.out.println("Integer");}
public static void hello(long x){System.out.println("long");}
public static void main(String[] args){
int i = 5;
hello(i);
}
}

Guess what would be output when we execute this java program. One can imagine of two answers. If you think Autoboxing will be done then "Integer" would be printed. But if you think widening of integer will take place then "long" would be printed. The only reason is, Sun did not want already existing programs to get different results, when they switch to Java 1.5. With earlier Java versions, widening would have taken place and long would have been printed, so is happening with Java 1.5 as well.

The question is, given that both methods exist, which one will be used? In other words, which one compiler think more desirable, Autoboxing or widening? The answer is that the compiler will choose widening over boxing, so the output would be "long".

Compiler can choose to perform following three operations
  • Widening
  • Autoboxing
  • Var-args

At any point in time there are two possible options like in above example then compiler would choose; "Widening over Autoboxing", "Widening over Var-args", "Autoboxing over Var-args".

Now the question is, what if there is a combination of these operations required? To get an answer of this question one needs to understand how widening works with objects. Widening in objects only in IS-A relation. If class Horse extends Animal then Horse can be widened to Animal for that reason any class can be widened to Object. Can Integer be widened to Long? Answer is NO because there is no IS-A relation there.

When there is a combination of operations required compiler will perform BoxingAndWidening but it will not perform WideningAndBoxing. It is just too much work for the compiler.

class WidenAndBox{
static void go(Long x){
System.out.println("This is from long");
}
public static void main(String[] args){
byte b = 5;
go(b);
}
}

Here Compiler needs to Widen byte to long first and then It can be boxed to Long which is not allowed (Searching for reason, Any references are welcome).

class BoxAndWiden{
static void go(Object x){
System.out.println("This is from object");
}
public static void main(String[] args){
byte = 5;
go(b);
}
}

Here compiler needs to be boxed into Byte first and then can be widen to Object because it follows IS-A relation.

This is it from my side. Feel free to share your ideas on this.

Labels: , , , , ,