当前位置: 首页 > 面试题库 >

编译器错误:引用调用不明确

窦伟
2023-03-14
问题内容

情况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

情况二

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

显示编译错误reference to call ambiguous。但是,我无法理解。为什么呢 但是,当我注释掉的任何call()方法时Case 2,它就可以正常工作。谁能帮助我了解一下,这是怎么回事?


问题答案:

在Java语言规范(JLS)中以非常正式的方式定义了查找最具体的方法。我在尝试尽可能删除正式公式的同时提取了适用的主要项目。

总之,适用于您的问题的主要项目是:

  • JLS 15.12.2:您的用例属于阶段3:

第三阶段(第15.12.2.4节)允许将重载与可变arity方法,装箱和拆箱相结合。

  • 然后,JLS 15.12.2.4基本上确定这两种方法均适用,因为可以将10转换为an Integer...或an int...。到目前为止,一切都很好。并得出以下结论:

在适用的可变引数方法中选择最具体的方法(第15.12.2.5节)。

  • 这使我们进入JLS 15.12.2.5。本段给出了一种条件方法,在这种条件下,一种Arity方法m(a...)比另一种Arity方法更具体m(b...)。在只有一个参数且没有泛型的用例中,它可以归结为:

m(a...)m(b...)iif 更具体a <: b,其中<:表示is a subtype of

它发生int是不是一个亚型IntegerInteger是不是一个亚型int

因此,要使用JLS语言,这两种call方法都是最大特定的(没有一种方法比另一种更特定)。在这种情况下,同一段的结论是:

  • 如果所有最大特定方法都具有等效的重写签名(第8.4.2节)[…] _=

    不是您的情况,因为不涉及泛型,并且Integer和int是不同的参数_

  • 否则,我们说方法调用是模棱两可的,并且会发生编译时错误。

注意

如果更换Integer...long...,例如,你必须int <: long和最具体的方法是call(int...)*。
同样,如果您将替换int...Number...,则该call(Integer...)方法将是最具体的。

*实际上,在Java 7之前的JDK中存在一个错误,在这种情况下会显示一个不明确的调用



 类似资料:
  • 注:内容翻译自官网文档 Compiler Invocation 当使用--java_out= 命令行标记时,protocol buffer编译器生成java输出。--java_out= 选项的参数是想编译器写java输出的目录。编译器为每个.proto文件输入创建一个单一的.java文件.这个文件包含一个单一的outer class定义,包含一些内嵌类和静态字段,基于.proto文件中的定义。 o

  • 问题内容: 我们要输入的值怎么 可能来自不同类型? 问题答案: 问题在于,编译器仅知道键类型为“未知”,但不知道映射键的类型和返回的类型是 相同的 未知类型(即使我们作为人类意识到这是相同的) 。 如果要使其工作,则必须通过 键入 方法来告诉编译器 相同的 未知类型,例如: __

  • 问题内容: 我在使用webstorm打字稿编译器时遇到问题。我有以下课程 因此,键入“ super”,我会在智能感知中看到所有rootData公共方法。但是在设置super.insert()之后,出现以下错误: TS2340:仅可通过’super’关键字访问基类的公共和受保护的方法 在TS游乐场中尝试过,它正在工作(认为是简化版本)。 谢谢你的帮助。 编辑:检查编译的javascript后,超级方

  • 问题内容: 我必须使用测试工具编译我的代码,但是,当该测试工具调用我的方法时,我收到此错误: “课程Course中的getCourseDetails方法不能应用于给定类型; 必需:java.lang.String,int,java.lang.String,boolean,java.lang.String.java.lang.String,double 找到:没有参数 原因:实际参数列表和形式参数列

  • 所以当我不使用我的maven实现时,我在编译我的应用程序时遇到了麻烦。它将编译没有任何麻烦与maven-gwt-plugin。 我收到的错误表示生成器无法获取其请求的类信息: 显然,该类存在并在maven实现中工作。我不明白为什么在使用eclipse“Java应用程序”运行配置进行标准构建时它不起作用。以下是我的跑步配置的设置: 有人知道这是怎么回事吗?

  • 问题内容: 我正在学习Google的新语言Go。我只是在尝试一些东西,我注意到,如果您声明一个变量并且不对其执行任何操作,则go编译器(在我的情况下为 8g )将无法 编译,并显示以下错误:。令我惊讶的是,大多数语言编译器只是 警告 您有关未使用的变量,但仍会编译。 无论如何,我能解决这个问题吗?我检查了编译器的文档,但看不到任何会改变此行为的内容。有没有一种方法可以删除以进行编译? 问题答案: