当两个方法存在于同一个类中时,为什么int ...变量被包装成long

OPK*_*OPK 5 java

下面的代码生成输出:In long.如果我将参数更改(int...x)(int x),则会打印出来It is int.这是为什么?

public class Sub  {

    void probe(int...x){
        System.out.println("It is int");
    }


    void probe(long x){
        System.out.println("In long");
    }

    public static void main(String[] args){
        int b = 4;
        new Sub().probe(b);
    }
}
Run Code Online (Sandbox Code Playgroud)

rge*_*man 8

Java编译器将首先选择一个方法而不考虑任何变量arity方法,即使用int....只有在找不到任何匹配方法时才会考虑具有变量arity的方法.这里,long匹配因为int可以long通过扩展的原始转换来提升.

JLS,第15.12.2支配编译器如何选择一个匹配的方法:

该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容.阶段是:

  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方法,装箱和拆箱相结合.

这里,仅执行步骤1,因为long匹配.


RE3*_*350 4

绑定按以下顺序进行。

1.Exact match (Ex.  int -->int)
2.Promotion (Ex. int-->long)
3.Autoboxing/Unboxing (Ex. int -->Integer)
4.Varags (Ex. int -->int...)
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下

int...x第四个, 而是long x第二,这就是你得到这个输出的原因。