java - 为什么重载方法的类型提升优先于可变参数

标签 java overloading variadic-functions

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”。但它应该是“long”,因为字节类型参数函数已经存在。但这里程序将字节值提升为 int,但事实不应该是这样。

请问有人可以澄清这里发生了什么吗?

最佳答案

JLS 15.12.2是要在此处查看的规范的相关部分。特别是 - 强调我的:

The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:

  • The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

    This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

  • The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

    This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.

  • The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

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

关于java - 为什么重载方法的类型提升优先于可变参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58546237/

相关文章:

java - 如何在 super(...) 中创建数组列表

c++ - 命名空间中的模板 friend bool重载冲突

java - 这个Java方法调用的歧义在哪里?

C++ SFINAE 解析顺序

java - 使用其他现有元素将 json 中不存在的元素反序列化为有意义的值?

java - 如何在 JavaFX 中制作 TimeSpinner?

c++ - C++ 函数重载中的意外行为

C++ 将类的重载 operator() 作为函数指针传递

c++ - 使用 va_list 和 printf 传递参数时的精度损失

java - Logback - 如何通过在日志语句上指定来写入任何日志级别?