编译器错误:引用调用模糊 [英] Compiler error : reference to call ambiguous

查看:192
本文介绍了编译器错误:引用调用模糊的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

案例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: 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 an int.... So far so good. And the paragraph concludes:

    • 从适用的角度中选择最具体的方法(§15.12.2.5)变量方法。

      The most specific method (§15.12.2.5) is chosen among the applicable variable-arity methods.




      • 这将我们带到 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 method m(b...). In your use case with one parameter and no generics, it boils down to:

        • m(a ...) m更具体(b ...) iif a< :b ,其中<:表示的子类型。

          m(a...) is more specific than m(b...) iif a <: b, where <: means is 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:



          • 如果所有最大特定方法都具有覆盖等价(§) 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.

          注意

          如果您用<$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆