Java 为什么重载方法的类型提升优先于varargs

Java 为什么重载方法的类型提升优先于varargs,java,overloading,variadic-functions,Java,Overloading,Variadic Functions,上述代码的输出为“int”。但它应该是“长”的,因为字节类型参数函数已经存在。但在这里,程序将字节值提升为int,但事实并非如此 有人能澄清一下这里发生了什么吗?是规范中的相关部分。特别是,强调: 该过程的其余部分分为三个阶段,以确保与JavaSE5.0之前的Java编程语言版本兼容。这些阶段是: 第一阶段(§15.12.2.2)执行重载解析,不允许装箱或拆箱转换,也不允许使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段 这保证了在Java SE 5.0之前的J

上述代码的输出为“int”。但它应该是“长”的,因为字节类型参数函数已经存在。但在这里,程序将字节值提升为int,但事实并非如此

有人能澄清一下这里发生了什么吗?

是规范中的相关部分。特别是,强调:

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

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

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

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

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

  • 第三阶段(§15.12.2.4)允许重载与可变算术方法、装箱和拆箱相结合

在您的例子中,第一阶段在不使用变量arity方法调用或装箱的情况下查找匹配项,因此这就是结果。正如规范中所指出的,这基本上是为了向后兼容。

是规范中的相关部分。特别是,强调:

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

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

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

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

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

  • 第三阶段(§15.12.2.4)允许重载与可变算术方法、装箱和拆箱相结合


在您的例子中,第一阶段在不使用变量arity方法调用或装箱的情况下查找匹配项,因此这就是结果。如规范中所述,这基本上是为了向后兼容。

如果方法重载,编译器将始终最后选择变量参数方法。将
byte
提升为
int
(加宽转换)将优于采用var arg参数的方法


这背后的原因是语言需要向后兼容。旧功能将优先于新功能。理解变量参数的一个简单方法是,加宽将击败装箱,装箱将击败var args。

如果方法重载,编译器将始终最后选择变量参数方法。将
byte
提升为
int
(加宽转换)将优于采用var arg参数的方法


这背后的原因是语言需要向后兼容。旧功能将优先于新功能。理解变量参数的一个简单方法是,加宽将击败装箱,装箱将击败var args。

请阅读关于在帖子中包含代码的文档,并在发布之前使用预览检查其是否合理。请阅读关于在帖子中包含代码的文档,在发布之前,使用预览来检查它是否合理。非常感谢Jon。这澄清了我的疑问。但是,我不能得到第三阶段。@ShipraVarshney你可以看看我的答案,以便更简单地理解。@ShipraVarshney:B
public class Test
{
    public static void printValue(int i, int j, int k)
    {
        System.out.println("int");
    }

    public static void printValue(byte...b)
    {
        System.out.println("long");
    }

    public static void main(String... args)
    {
        byte b = 9;
        printValue(b,b,b);
    }
}