【问题标题】:Variable argument function ambiguity变量参数函数歧义
【发布时间】:2010-09-27 10:55:54
【问题描述】:
public static void main(String[] args) {
System.out.println(fun(2,3,4));
}
static int fun(int a,int b,int c)
{
return 1;
}
static int fun(int ... a)
{
return 0;
}
输出:
1
问题:
在上述情况下,为什么函数 fun 选择第一个函数而不是第二个函数。由于无法确定用户实际想要调用哪个 fun,选择的依据是什么?
【问题讨论】:
标签:
java
variadic-functions
overloading
【解决方案1】:
基本上对特定呼叫有偏好。除此之外,这意味着可以针对少量参数进行优化,避免在执行时无意义地创建数组。
JLS 并没有说得很清楚,但它在section 15.12.2.5 中,如果某些条件成立,则讨论固定数量方法比另一种方法更具体的部分 - 在这种情况下它们确实如此。基本上它更具体,因为有更多的调用将对可变参数方法有效,就好像有相同数量的参数但参数类型本身更一般。
【解决方案2】:
当遇到这些歧义时,编译器总是选择精确的方法。在您的场景中,具有三个参数的 func 比一个变量参数更精确,因此被调用。
编辑:已根据 skeet 的评论进行编辑。
【解决方案3】:
如果你测试这个表达式:
System.out.println(fun(2,3,4));
System.out.println(fun(2,3));
System.out.println(fun(2,3,4,7));
输出是
1
0
0
Java 编译器首先检查其声明与调用的确切参数匹配的方法,否则,它会搜索替代方法匹配。
【解决方案4】:
此行为允许解析两个重载的变量参数调用:
addStates(String... states)
addStates(Enum... states)
调用 addStates() 会产生编译歧义问题。添加第三种方法:
addStates(){
addStates(new String[0]);
}
这允许选择更具体的第三个 addStates() 来解决不确定调用哪个变量类型参数方法的歧义问题。