java中的变量参数
我怀疑为什么编译器没有显示任何错误,因为doit(4,5)导致了歧义java中的变量参数,java,Java,我怀疑为什么编译器没有显示任何错误,因为doit(4,5)导致了歧义 当我运行代码时,我得到的输出是ad而不是b why?编译器试图匹配最具体的替代方案。然而,可以说,这会导致歧义错误 来自Java语言规范 如果一个方法调用可以访问并适用于多个成员方法,则有必要选择一个成员方法来为运行时方法分派提供描述符。Java编程语言使用的规则是选择最具体的方法 JLS规定了用于解决歧义的规则。简化的版本是,编译器首先尝试将调用与将varadic参数视为简单数组的可用重载相匹配。如果成功了,就是这样。如果
当我运行代码时,我得到的输出是ad而不是b why?编译器试图匹配最具体的替代方案。然而,可以说,这会导致歧义错误 来自Java语言规范 如果一个方法调用可以访问并适用于多个成员方法,则有必要选择一个成员方法来为运行时方法分派提供描述符。Java编程语言使用的规则是选择最具体的方法
JLS规定了用于解决歧义的规则。简化的版本是,编译器首先尝试将调用与将varadic参数视为简单数组的可用重载相匹配。如果成功了,就是这样。如果失败,它将再次尝试将最后一个参数视为varadic 在这种情况下,第一轮匹配会给出一个确定的匹配
如果您感兴趣,中给出了确定应使用何种方法的JLS规则。(警告:实际的JLS规则比上面的简化版本涉及的内容要多得多,而且使用的语言/符号非常技术性。) 编译器总是试图解析调用到最特定的函数调用。它可以在这种情况下找到方法A。这不是一个bug,但是如果你认为它不是编译器错误,那就在规格中。一旦自动装箱开始发挥作用,您应该看到从中可以得到的疯狂的东西。Java语言规范定义了应该调用的第一个方法(“a”)而不是“b”) 看 为了保持与以前的Java版本(在引入varargs之前)的向后兼容性,编译器将始终选择具有确切参数数的方法,即使varargs方法也存在
至于您是否得到警告,编译器可以自由添加额外的警告,并且可能有一些确实警告了这种情况,我想您的没有(至少没有您的设置)这是他们在执行varargs规范时做出的妥协(很难知道调用了哪个)。因此,建议不要重载varargs方法。引自: 一般来说,您不应该重载varargs方法,否则程序员将很难确定调用哪个重载 将被编译器视为
public static String doit(int ...val)
{
return "b";
}
当传递doit(2,2)时,将调用第1个方法,因为参数不是数组
当传递doit(2,2,2)时,参数将转换为数组并传递给第二个方法
将第一个方法更改为
public static String doit(int[] val)
{
return "b";
}
调用doid(2,2),它将显示错误
public static String doit(int x,int ...y)
{
return"a";
}
public static String doit(int x,int ...y)
{
return"a";
}
doit(int, int[]) is ambigious.