Monday, July 2, 2012

Autoboxing Overloading - Part 3


I've created a new topic for overloading because it involves Autoboxing and as you'll see there are some tricks that need to seen closely.
As you know to overload a method you have to change its arguments and the compiler will decide which method to invoke.
Let's see a simple example of overloaded method:

public class Overloaded {
public static void doSomething(byte b) {
System.out.println("byte " + b);
}
public static void doSomething(double f) {
System.out.println("double " + f);
}
public static void doSomething(int i) {
System.out.println("int " + i);
}
public static void main(String[] args) {
short s = 9;
int i = 45;
float f = 12.55f;
doSomething(s) ; // Prints int 9
doSomething(i) ; // Prints int 45
doSomething(f) ; // Prints double 12.55
}
}
view raw gistfile1.java hosted with ❤ by GitHub

Widening
Ok that's a easy one, the important thing here is the statement at line 19, it invokes the method doSomething(int i), despite we're passing a short value you know that int supports short because int is bigger than short, that's why the method doSomething(int i) was called instead of doSomething(byte b). Also if the method doSomething(int i) did not exist the method doSomething(double f) would be invoked.

Now take a look at the following image:


The image tells us that Widening beats Boxing and Var-args and Boxing beats Var-args, so to get a better understanding of it keep in your mind this rule.
Let's see it in action

package br.com.ocjp.autoboxing;
public class AutoBoxingBeats {
public static void doIt(long value) {
System.out.println("Primitive long");
}
public static void doIt(Integer value) {
System.out.println("Integer");
}
public static void doIt(int... value) {
System.out.println("var-args");
}
public static void doThat(Integer value) {
System.out.println("Integer");
}
public static void doThat(int... value) {
System.out.println("var-args");
}
public static void doSomething(Object s) {
System.out.println("Object");
}
public static void doSomething(Number s) {
System.out.println("Number");
}
public static void main(String[] args) {
int n = 100;
doIt(n); // Prints Primitive long - Widening
doThat(n); // Prints Integer - Boxing
doSomething(n); // Prints Number - Variable Reference Widening
}
}
view raw gistfile1.java hosted with ❤ by GitHub

!Important

You cannot widen an Integer wrapper to a Long, so keep it in your mind it's not able to widen Wrapper to Wrapper.
Looking closely to the doSomething() method what happens first is a boxing int - Integer and then Integer is a Number.

Finally sometimes the compiler cannot tell apart which overloaded method is eligible to be invoke which results in a compiler error, for more details about this look it out. click here

No comments: