类型提升和方法重载(多个选项)

时间:2019-06-06 19:03:31

标签: java overloading type-promotion

当由于类型提升而存在多个可接受的方法时,哪些因素将决定执行哪种方法?

这是示例代码

public class Demo {
  public static void main(String[] args) {
    byte a = 100;
    long b = 10000;
    test(a, b);
  }

  public static void test(long a, double b) {
    System.out.println("Method 2");
  }

  public static void test(int a, float b) {
    System.out.println("Method 1");
  }
}

输出为:Method 1,但如果我注释掉Method 2,则为test(int a, float b)

那是为什么?它会尝试进行最少的类型提升吗?它会尝试提倡论据1,然后提倡论据2吗?是否基于某种优先级?

我已经看到了这个问题:How method-overloading and primitive types works?,其中包括以下语句:

  
      
  1. 如果识别出一种以上的方法,则选择最具体的一种。
  2.   

我想在如何从所有可能的方法中选择要执行的最终方法的后面提供更多细节。我知道类型升级会发生,但是如果类型升级后有多个选项,编译器如何确定最终方法?换句话说,根据上面的陈述,更具体是什么?

1 个答案:

答案 0 :(得分:1)

尽管您链接到的问题和答案已经在某种程度上涵盖了这一点,但是您可以在这里查看更具体的案例(双关语意)。特别是,相关的“决策路径”指的是JLS中15.12.2.5. Choosing the Most Specific Method的(有些复杂)描述。

该部分首先说:

  

非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法而没有编译时错误,则一个方法比另一个方法更具体。

这已经非常有用了,因为您可以看到,传递给test(int, float)方法的任何内容 也可以传递给test(long, double)方法。所以第一个更具体。

但请参考规范:

  

对于使用参数表达式m1的调用,如果满足以下任一条件,则一个适用的方法m2比另一个适用的方法e1, ..., ek更具体:

     
      
  • m2不是通用的,并且m1m2适用于严格或宽松的调用,并且m1具有形式参数类型S 1 ,...,S n m2具有形式参数类型T 1 ,...,T n ,对于所有i(1≤i≤n,n = k),对于参数ei,类型S i 比T i 更具体。
  •   
     

...

     

如果S <:T

,则对于任何表达式,类型S都比类型T更具体。

后者是指4.10. Subtyping 部分,其中超类型关系 :>被指定为直接超类型关系 > 1 ,并且后者包括用于原始类型的

  • double> 1 float
  • long> 1 int

因此,方法test(int, float)test(long, double)更具体,因为intlong的子类型,而floatdouble的子类型。


(请注意,这里的“子类型”的概念也适用于原始类型,不仅适用于“类之间的继承”)