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

Type Promotion and Method Overloading (Multiple Options)

当因为类型提升有多个可接受的方法时,决定执行哪个方法的因素是什么?

这是示例代码

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?是否基于某种优先级?

我看过这个问题:,其中包含语句:

  1. If more than one method was identified, pick the most specific one.

我想了解有关如何在所有可能的方法中选择要执行的最终方法的更多细节。我知道会发生类型提升,但如果类型提升后有多个选项,编译器如何确定最终方法?也就是说,从上面的说法,更具体是什么?

虽然您链接到的问题和答案已经在一定程度上涵盖了这一点,但您可以在此处查看更具体的案例(双关语)。特别是,相关 "path to the decision" 指的是 JLS 中 15.12.2.5. Choosing the Most Specific Method 的(有点复杂)描述。

该部分首先说:

The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error.

这已经非常有用了,因为您可以看到无论您传递给 test(int, float) 方法什么, 都可以 也传递给 test(long, double)方法。所以第一个更具体。

但参考规范:

One applicable method m1 is more specific than another applicable method m2, for an invocation with argument expressions e1, ..., ek, if any of the following are true:

  • m2 is not generic, and m1 and m2 are applicable by strict or loose invocation, and where m1 has formal parameter types S1, ..., Sn and m2 has formal parameter types T1, ..., Tn, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ n, n = k).

...

A type S is more specific than a type T for any expression if S <: T

后者引用 4.10. Subtyping 部分,其中 超类型关系 :> 被指定为 [=52= 的自反和传递闭包]direct supertype relation >1,后者包括,for primitive types

  • double >1 float
  • long >1 int

所以方法 test(int, float)test(long, double) 更具体,因为 intlong 的子类型,而 float 是 [=24 的子类型=].


(注意这里"subtypes"的概念也适用于原始类型,而不仅仅是"inheritance between classes")