为什么这不会产生歧义?

时间:2015-08-12 14:15:32

标签: java overloading javac variadic-functions ambiguous-call

我刚刚编写了一些具有以下结构的代码:

public void method(int x) {
    //...
}

public void method(int x, String... things) {
    //...
}

我很惊讶这个编译,如果我调用

method(3);
然后它会选择第一个。显然,这在某种意义上是自然选择的,但如果第一种方法不存在,这将是调用第二种方法的合理方式(使用空的varargs数组)。所以肯定它应该被认为是模糊的并产生编译时错误?

或者这被视为特例?

这样对待它似乎是错误的,因为这意味着添加新方法可能会破坏现有代码,这不是一个非常幸福的事态。

(Goodness只知道如果第一个被添加为包含第二个子类的子类的新方法,你最终会调用哪个...)

2 个答案:

答案 0 :(得分:10)

根据Java语言规范的Chapter 15,搜索适用的方法分三个阶段进行。

  

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

因此,第一种方法已被认为适用于第一阶段。其余阶段被跳过; String ...方法只会在第三阶段考虑:

  

第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。

答案 1 :(得分:0)

第一种方法的参数类型是

int x

第二种方法的参数类型是

int x, String[] things

因此,的两种方法具有相同的签名,并且没有歧义。 @Glorfindel解释了Java如何决定调用哪个方法,但如果你想调用没有任何things的第二个方法,你可以传入一个空数组。

method(6, new String[0]);
相关问题