Java方法重载

use*_*462 3 java primitive overloading wrapper

以下方法返回输出:在原始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);
      }
  }
Run Code Online (Sandbox Code Playgroud)

然而,如果我将show方法的arguement类型从int更改为Integer,则输出返回为:in primitive float 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);
      }
  }
Run Code Online (Sandbox Code Playgroud)

但是现在如果我将第二种方法的争论类型从float更改为Float,则输出再次更改为:in Integer 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);
      }
  }
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我理解这种行为

rge*_*man 7

发生这种情况是因为在尝试查找要调用的匹配方法时,Java会考虑不需要装箱或取消装箱转换的方法,然后才会考虑需要装箱或取消装箱转换的方法.

JLS第15.12.2节规定:

  1. 第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用.如果在此阶段没有找到适用的方法,则处理继续到第二阶段.

这保证了在Java SE 5.0之前在Java编程语言中有效的任何调用都不会因为引入变量arity方法,隐式装箱和/或取消装箱而被认为是不明确的.但是,变量arity方法(第8.4.1节)的声明可以更改为给定方法方法调用表达式选择的方法,因为变量arity方法在第一阶段被视为固定arity方法.例如,在已声明m(Object)的类中声明m(Object ...)会导致不再为某些调用表达式(例如m(null))选择m(Object),因为m(Object [] )更具体.

  1. 第二阶段(§15.12.2.3)执行重载解析,同时允许装箱和拆箱,但仍然排除使用变量arity方法调用.如果在此阶段没有找到适用的方法,则处理继续到第三阶段.

这确保了如果通过固定的arity方法调用适用,则永远不会通过变量arity方法调用来选择方法.

  1. 第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合.

(大胆强调我的)

在第一个示例中,该int方法是精确匹配并且接管该float方法,即使它适用于没有装箱/拆箱的情况.

在第二个例子中,该float方法适用于没有装箱/拆箱,但该Integer方法需要装箱,因此float选择该方法.

在第三个示例中,两种方法都需要装箱,因此Integer现在选择该方法.