2

在 java 中,我面临一个函数歧义。基本上我正在重载一个可变参数函数
我正在定义函数

        static void f(Integer... a)
        {
            // .. some statements

        }

        static void f(float f,Integer... a)
        {
            // .. some other statements
        }

可以通过以下函数调用来调用函数

f(1,2);
f(1.2f,1,2);

并弹出此错误消息

error: reference to f is ambiguous, both method f(Integer...) in Test and method f(float,Integer...) in Test match
        f(1,2);
        ^

有人可以帮我理解我是否在这里遗漏了java中的任何基本概念。谢谢。。

4

4 回答 4

3

这两种方法都可以采用您输入的第一个参数f(1,2);,这就是您产生歧义的原因。如果你愿意

f((float)1,2);

例如,您不会收到错误消息

于 2013-08-04T14:23:05.927 回答
3

在 Java 语言中,int 值可以自动转换为 float 值(不允许相反)。

因此,当您拨打

f(1,2)

Java 编译器匹配自动类型转换允许的所有可能的签名,即:

  • f(整数,整数)
  • f(浮点数,整数)
  • f(浮动,浮动)
  • f(整数,浮点数)
  • f(int, ...)
  • f(浮点数, ...)

存在歧义,编译器不知道您是打算调用 f(int, ...) 还是 f(float, float)。

于 2013-08-04T14:23:57.503 回答
2

当有几种方法适用时,编译器会尝试找到最具体的一种。如果两种方法是最具体的,则存在歧义并且您会收到错误。

总结一下(实际规则稍微复杂一些):

  • 编译器确定对于f(1, 2),两种方法都适用(1 可以是整数或浮点数)
  • 然后编译器需要确定哪种方法更具体float:在你的情况下,没有一个在规范中定义的意义上更具体,因为和之间没有关系Integer(例如:如果你有一个f(int i, Integer... j)vs. f(float f, Integer... j),前者会更具体因为intfloat原语更具体。同样,如果你有 af(Number f, Integer... i)与 a f(Integer... i),后者会更具体,因为Integerextends Number)。
于 2013-08-04T14:29:29.220 回答
1

运行时可以选择使用整数列表强制转换函数以调用任一函数。这就是混乱所在。您提供的任何整数列表也可以转换为另一个调用,其中单个前导浮点数后跟整数列表。

于 2013-08-04T14:19:35.737 回答