下面的代码会产生语法错误:
The method
f(int[])
is ambiguous for the type C
我的代码:
public class C{
public static void f(int... i)
{
System.out.println("a");
}
public static void f(Integer... i)
{
System.out.println("b");
}
public static void main(String[] args) {
f(new Integer(2));
}
}
如果我使用数组符号 []
而不是 ...
并使用 f(new Integer[]{3,4, 5})
,编译器可以正确判断我要使用哪种方法。
编译器无法决定使用 ...
调用哪个函数的原因是什么?
最佳答案
在JLS, Secion 15.12, "Method Invocation Expressions" 中解释了为特定调用站点找到“正确”方法的过程。 .经过简短的基本健全性检查前奏后,相关部分从 section 15.12.2.1, Identify Potentially Applicable Methods 开始。 .根据此定义,在您的情况下,这两种方法都可能适用。
后续流程分为三个阶段。在您的情况下,该方法是一个可变元数 方法(由于“varargs”)。所以它立即从 15.12.2.4, Phase 3: Identify Applicable Variable Arity Methods 开始.
The method m is an applicable variable-arity method if and only if all of the following conditions hold:
- For 1 ≤ i < n, the type of ei, Ai, can be converted by method invocation conversion to Si.
- ...
(其他条件与此无关)
Method Invocation Conversion (JLS, 5.3)允许进行以下转换:
- 身份转换(§5.1.1)
- 扩大原始转换(§5.1.2)
- 扩大引用转换(§5.1.5)
- 装箱转换 (§5.1.7) 之后可选择加宽引用转换
- 拆箱转换(§5.1.8),可选地后跟扩大的原始转换。
从 Integer
到 Integer
的转换是身份转换(第一个要点)。从 Integer
到 int
的转换是拆箱转换(最后一个要点)。
因此根据规范,这两种方法都是“适用的可变元数方法”。
关于java - 方法调用与可变参数运算符不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25465147/