Java method overloading

the following method returns the output: in the primitive method int arg

  public class TestMethodOverloading {
          private void show(int a){
              System.out.println("in primitive int arg method");
          }
         private void show(float a){
            System.out.println("in primitive float arg method");
          }
         public static void main(String[] args) {
         TestMethodOverloading tmo = new TestMethodOverloading();
         tmo.show(4);
      }
  }

      

If I change the type of the argument of the show method from int to Integer then the output is returned as: in the primitive method float arg

     public class TestMethodOverloading {
          private void show(Integer a){
                System.out.println("in Integer arg method");
          }
         private void show(float a){
            System.out.println("in primitive float arg method");
          }
         public static void main(String[] args) {
         TestMethodOverloading tmo = new TestMethodOverloading();
         tmo.show(4);
      }
  }

      

But now if I change the argument type of the second method from float to Float, then the output changes to: in the Integer arg method

      public class TestMethodOverloading {
          private void show(Integer a){
                System.out.println("in Integer arg method");
          }
         private void show(Float a){
            System.out.println("in primitive float arg method");
          }
         public static void main(String[] args) {
         TestMethodOverloading tmo = new TestMethodOverloading();
         tmo.show(4);
      }
  }

      

Can anyone help me understand this behavior

+3


source to share


2 answers


This is because when trying to find mapping methods to call, Java will look at methods where boxing or unboxing conversion is not required, before it looks at methods where boxing or unboxing conversion is required.

JLS section 15.12.2 states:

  • The first phase (§15.12.2.2) performs overload resolution without allowing boxing conversion or unboxing, or using a method call to the arity variable. If no applicable method is found at this stage, processing continues until the second phase .

This ensures that any calls that were valid in the Java programming language prior to Java SE 5.0 are not considered ambiguous as a result of injecting arity variable methods, implicit boxing, and / or unboxing. However, declaring a method on an arity variable (§8.4.1) may change the method chosen to express a method invocation of a given method, since the arity variable method is treated as a fixed arity method in the first phase. For example, declaring m (Object ...) in a class that already declares m (Object) results in m (Object) no longer being selected for some call expressions (such as m (null)) like m (Object [])) is more specific.

  1. The second phase (§15.12.2.3) performs overload resolution, and allows boxing and unboxing , but still precludes the use of calling the arity variable method. If no applicable method is found at this stage, processing continues until the third phase.

This ensures that the method is never selected by calling the arity variable method if applicable by calling the fixed arity method.

  1. The third stage (§15.12.2.4) allows you to combine overloading using the arity variable, boxing and unboxing methods.

(bold emphasis mine)



In the first example, the method int

is an exact match and is taken by method float

even if applicable without boxing / unboxing.

In the second example, the method is float

applicable without boxing / unboxing, but the method Integer

requires boxing, so the method is selected float

.

In the third example, both methods require boxing, so the method is now selected Integer

.

+6


source


In a java method call, the conversion extension (int -> float) takes precedence over the box conversion (int -> Integer). so in chunk 2 private void show(float a)

will execute and in chunk 2 private void show(Integer a)

will be canceled.



0


source







All Articles