编译器错误:引用调用模糊 [英] Compiler error : reference to call ambiguous
问题描述
案例1
static void call(Integer i) {
System.out.println("hi" + i);
}
static void call(int i) {
System.out.println("hello" + i);
}
public static void main(String... args) {
call(10);
}
案例1的输出:hello10
案例2
static void call(Integer... i) {
System.out.println("hi" + i);
}
static void call(int... i) {
System.out.println("hello" + i);
}
public static void main(String... args) {
call(10);
}
显示编译错误调用不明确的参考
。但是,我无法理解。为什么?但是,当我从案例2
中注释掉任何 call()
方法时,它运行正常。任何人都可以帮助我理解,这里发生了什么?
Shows compilation error reference to call ambiguous
. But, I was unable to understand. Why ? But, when I commented out any of the call()
methods from Case 2
, then It works fine. Can anyone help me to understand, what is happening here ?
推荐答案
找到最具体的方法是以非常正式的方式定义的Java语言规范(JLS)。我在尝试尽可能删除正式公式时提取了下面的主要项目。
Finding the most specific method is defined in a very formal way in the Java Language Specificaion (JLS). I have extracted below the main items that apply while trying to remove the formal formulae as much as possible.
总之,适用于您的问题的主要项目是:
In summary the main items that apply to your questions are:
- JLS 15.12.2 :您的用例属于第3阶段:
- JLS 15.12.2: your use case falls under phase 3:
第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。
The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
- 然后 JLS 15.12.2.4 基本上确定两种方法都适用,因为10可以转换为
Integer ...
或int ...
。到现在为止还挺好。该段落总结如下: - Then JLS 15.12.2.4 basically determines that both method are applicable, because 10 can be converted to both an
Integer...
or anint...
. So far so good. And the paragraph concludes: - 这将我们带到 JLS 15.12.2.5 。本段给出了arity方法
m(a ...)
比另一个arity方法更具体的条件m(b ...)
。在具有一个参数且没有泛型的用例中,它归结为: - Which brings us to JLS 15.12.2.5. This paragraph gives the conditions under which an arity method
m(a...)
is more specific than another arity methodm(b...)
. In your use case with one parameter and no generics, it boils down to: - 如果所有最大特定方法都具有覆盖等价(§) 8.4.2)签名[...] =>不是你的情况,因为没有涉及泛型,Integer和int是不同的参数
- 否则,我们说方法调用是不明确的,并且发生编译时错误。
- If all the maximally specific methods have override-equivalent (§8.4.2) signatures [...] => not your case as no generics are involved and Integer and int are different parameters
- Otherwise, we say that the method invocation is ambiguous, and a compile-time error occurs.
从适用的角度中选择最具体的方法(§15.12.2.5)变量方法。
The most specific method (§15.12.2.5) is chosen among the applicable variable-arity methods.
m(a ...)
比m更具体(b ...)
iifa< :b
,其中<:
表示是
的子类型。
m(a...)
is more specific thanm(b...)
iifa <: b
, where<:
meansis a subtype of
.
碰巧 int
不是 Integer的子类型
和整数
不是 int
的子类型。
It happens that int
is not a subtype of Integer
and Integer
is not a subtype of int
.
要使用JLS语言,因此调用
方法都是最具体的(没有方法比其他方法更具体)。在这种情况下,同一段落结束:
To use the JLS language, both call
methods are therefore maximally specific (no method is more specific than the other). In this case, the same paragraph concludes:
注意
如果您用<$ c $替换整数...
c> long ... 例如,你有 int< ;: long
,最具体的方法是 call(int ...)
*。
同样,如果你用<$ c $替换 int ...
c> Number ... ,调用(Integer ...)
方法将是最具体的。
If you replaced Integer...
by long...
for example, you would have int <: long
and the most specific method would be call(int...)
*.
Similarly, if you replaced int...
by Number...
, the call(Integer...)
method would be the most specific.
*实际上 JDK之前的一个错误Java 7会在那种情况下显示模糊的调用。
这篇关于编译器错误:引用调用模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!