为什么类型的推广优先于可变参数的重载方法为什么类型的推广优先于可变参数的重载方法(Why does

2019-05-12 05:54发布

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);
    }
}

上面的代码的输出是“int”。 但它应该是“长”,因为字节类型参数的功能已经存在。 但这里的程序正在推动字节值来诠释,但它不应该是这样的。

请某人能澄清这到底是怎么回事呢?

Answer 1:

可变参数的方法总是会通过在重载方法情况下,编译被选择的最后一个。 一个促进byteint (扩大变换)将在采用一个无功arg参数的方法是优选的。

这背后的原因是语言需要向后兼容。 较早的功能将优先于较新的功能。 理解一个简单的方法是什么JLS说,关于可变参数是扩大将打拳击和拳击将击败VAR-ARGS。



Answer 2:

JLS 15.12.2是规范的相关位看这里。 特别是 - 重点煤矿:

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

  • 第一阶段(§15.12.2.2)执行重载而不允许拳击或取消装箱转换,或使用可变元数的方法调用的。 如果在此阶段没有发现适用方法然后处理继续到第二阶段。

    这保证了这是有效的在Java SE 5.0之前的Java编程语言中的任何调用并不认为是不明确引进的变量元数法,隐式装箱和/或拆箱的结果。 然而,可变元数法(§8.4.1)的声明可以改变选择用于给定方法的方法调用表达的方法中,因为可变的arity方法作为在第一阶段的固定元数的方法进行处理。 例如,声明m(Object...)其中已经声明一个类m(Object)导致m(Object)不再被选择用于某些调用表达式(如m(null)m(Object[])是更具体的。

  • 第二阶段(§15.12.2.3)执行重载解析,同时允许装箱和拆箱,但仍排除使用可变元数的方法调用的。 如果在此阶段没有发现适用方法然后处理继续到第三阶段。

    这确保了一种方法,通过从未可变元数的方法调用选择,如果它是适用通过固定元数的方法调用。

  • 第三阶段(§15.12.2.4)允许重载具有可变元数的方法,拳击,和取消装箱组合。

在你的情况下,第一阶段找到一个匹配,而无需使用可变参数数量的方法调用或打拳,因此这就是结果。 正如规范所指出的,这基本上是为了向后兼容。



文章来源: Why does type-promotion take precedence over varargs for overloaded methods