使用varargs重载Java 7

使用varargs重载Java 7,java,overloading,variadic-functions,Java,Overloading,Variadic Functions,可能重复: 谁能给我解释一下这个是怎么工作的 class Vararg { static void vararg(int... x) { System.out.println("Integer..."); } static void vararg(long... x) { System.out.println("long..."); } public static void main(String [] args

可能重复:

谁能给我解释一下这个是怎么工作的

class Vararg {
    static void vararg(int... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) { 
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}
获取编译时错误

class Vararg {
    static void vararg(Integer... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) {
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}

还有编译时错误。对varargs使用重载时的机制是什么?这是一个重载varargs方法的错误吗?

实际上,要确定哪种方法是适用的:

  • 首先尝试在不使用装箱/取消装箱或varargs的情况下查找方法
  • 第二,尝试找到一种方法,允许装箱/取消装箱,但不使用varargs
  • 第三,允许装箱、拆箱和变位
在您的情况下,第三步适用于所有方法

然后,编译器确定哪些方法适用,以及一种方法是否比另一种方法更具体。具体规则见附件。简而言之,它查看类型并检查一个类型是否比另一个更具体(即,对于引用,一个类型是另一个类型的子类,或者对于原语,一个类型比另一个更窄)

就你而言:

  • 在示例1中,两种方法都适用,但
    int
    long
    更具体,因此选择了
    vararg(int…)
  • 在示例2中,
    Integer
    long
    没有特定关系(一个是引用,另一个是primitve),因此两者都是最大特定的,并且存在导致编译错误的歧义

编辑


我以为你是说你的第一个例子是编译的,而不是第二个(这是预期的行为)。您似乎在说这两个版本都不编译,在这种情况下,这可能是由于您的
javac
版本中的一个bug造成的,这个bug已经用java7修复了。请参阅“大多数特定Varargs方法选择中的更改”一节中的详细信息。

由于您在vararg(type…var)方法中发送了int值,并且重载方法包含一个整数和一个long,因此int值会自动转换为long,从而产生歧义。在重载方法中使用不同的参数类型

class Vararg {
static void vararg(Integer... x) {
    System.out.println("Integer..."); 
}

static void vararg(String... x) {
    System.out.println("String..."); 
}

public static void main(String [] args) {
    int s = 0;
    vararg(s,s);
}

}

方法的运行时参数是模糊的,具体的RFE是