编译器错误:对调用不明确的引用 [英] Compiler error : reference to call ambiguous

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

问题描述

案例 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);
}

显示编译错误调用模棱两可的引用.但是,我无法理解.为什么 ?但是,当我从 Case 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 节)允许将重载与可变数量方法、装箱和拆箱相结合.

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.本段给出了一个元数方法 m(a...) 比另一个元数方法 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 的子类型,Integer 也不是int 的子类型.

          It happens that int is not a subtype of Integer and Integer is not a subtype of int.

          为了使用 JLS 语言,两个 call 方法因此是最具体的(没有方法比另一个更具体).在这种情况下,同一段落的结论是:

          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 是不同的参数
          • 否则,我们说方法调用不明确,会出现编译时错误.

          注意

          例如,如果您将 Integer... 替换为 long...,您将拥有 int <: long 和最具体方法是 call(int...)*.
          同样,如果将 int... 替换为 Number...call(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.

          *实际上 Java 7 之前的 JDK 中存在一个错误在这种情况下调用.

          这篇关于编译器错误:对调用不明确的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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