Method overloading with Widening, Autoboxing and Var-args - Who beats whom in java?


  1. Widening - We discussed a lot about widening in Program 5.2 and 5.3
  2. Var-args

Now, Let's understand following important concepts where >
  1. AutoBoxing beats Var-args
  2. Widening beats Autoboxing
  3. Widening beats Var-args

  1. widening and then AutoBoxing is not allowed in one operation.
  2. But, AutoBoxing and then widening is allowed in one operation.


  1. AutoBoxing beats Var-args
public class AutoboxingBeatsVarargs {
   static void m(Integer i1, Integer i2) {
          System.out.println("Integer i1, Integer i2");
   }
   static void m(Integer...i) {
          System.out.println("int...i");
   }
   public static void main(String[] args) {
          int i = 3;
          m(i, i);
   }
}
/*OUTPUT
Integer i1, Integer i2
*/
Compiler prefers to do AutoBoxing than invoking Var-args. Hence, AutoBoxing beats Var-args

  1. Widening beats Autoboxing
public class WideningBeatsAutoboxing {
   public static void main(String[] args) {
          int i = 3;
          m(i);
   }
   static void m(Integer i) {
          System.out.println("Integer");
   }
   static void m(double d) {
          System.out.println("double");
   }
}
/*OUTPUT
double
*/
Compiler prefers to do Widening than doing Autoboxing. Hence, Widening beats Autoboxing

  1. Widening beats Var-args
public class WideningBeatsVarargs {
  
   public static void main(String[] args) {
          int i = 3;
          m(i, i);
   }
   static void m(float f1, float f2) {
          System.out.println("float f1, float f2");
   }
   static void m(int... i) {
          System.out.println("int...i");
   }
  
}
/*OUTPUT
float f1, float f2
*/

Compiler prefers to do Widening than invoking Var-args. Hence, Widening beats invoking Var-args


You can remember above 3 conversions in this way >
Widening > Autoboxing > Var-args
(Note: It’s not any standard convention)

  1. widening and then AutoBoxing is not allowed in one operation.
As a solution to above program we can perform Widening and then AutoBoxing in multiple steps/operations.
public class WideningAndThenAutoBoxingInMultipleSteps {
   public static void main(String[] args) {
          int i = 3;
          double d = i; // Widening
          Double d2 = d; // AutoBoxing         
   }
}


  1. But, AutoBoxing and then widening is allowed in one operation.

public class AutoBoxingAndThenWidening {
   public static void main(String[] args) {
          int i = 3;
          Number num = i; //AutoBoxing and then widening
          Integer i1 = (Integer) num;
   }
}

But how does AutoBoxing and then widening happens internally in one operation?
Java compiler will convert above code into -
public class AutoBoxingAndThenWidening {
   public static void main(String[] args) {
          int i = 3;
          Number num = Integer.valueOf(i); //AutoBoxing and then widening
          Integer i1 = (Integer) num;
          System.out.println(i1);
   }
}
Number num = Integer.valueOf(i);
1) int i is Autoboxed to Integer object,
2) As Number is superclass of Integer, reference variable of Number can refer to Integer object (this is widening of Integer object),

Integer i1 = (Integer) num;
3) num is casted to Integer (java.lang.Object's object was never formed, originally it was Integer's object only but compiler won't trust us for doing such downcasting. Hence, we need explicit casting)

RELATED LINKS>

Autoboxing and unboxing in java - How it works internally in detail with 10 examples- Widening, AutoBoxing and Var-args

Java caches Integer objects formed from primitive int values between values -128 to 127

10 points on why we are still using primitive data types in java ? When to use primitive type and wrapper classes?

Change boxing or Unboxing Setting in eclipse in java - Advantages


eEdit
Must read for you :