2

为什么编译器在这里抱怨?

public static void main(String[] args) {
    flipFlop(new Integer(11), 20f);
}

private static void flipFlop(int i, Float iRef) {

}

private static void flipFlop(int i, float j) {

}

但不是在这里?

public static void main(String[] args) {
    flipFlop(11, 20f);
}

private static void flipFlop(int i, Float iRef) {

}

private static void flipFlop(int i, float j) {

}

这很奇怪,因为它应该在两种情况下都能解决。

在某些情况下,只有第二个参数可能会变得模棱两可,但第一个参数不会。那么,如果我更改第一个,为什么会抱怨。

4

4 回答 4

4

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

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

  • 编译器首先在不允许可变参数或(取消)装箱的情况下查找适用的方法。在您的第二个示例中,只有第二种方法适用并被选择。在您的第一个示例中,需要对 Integer 进行拆箱,并且在此阶段不能选择任何方法。
  • 然后编译器允许装箱和拆箱。在您的第一个示例中,这两种方法都适用。
  • 然后编译器确定哪种方法更具体:在您的情况下,没有一个在规范中定义的意义上更具体,因为浮点数和浮点数之间没有关系(例如:如果您有一个浮点数和一个双精度数,浮点数会更多具体的;如果你有一个浮点数和一个数字,浮点数会更具体)。
于 2013-08-03T09:37:42.610 回答
1

在第二种情况下,您的方法签名完全匹配。在第一种情况下,它是模棱两可的。你是拆箱Integer还是拆箱Float

于 2013-08-03T09:37:35.333 回答
0

在第一种情况下,您将值装箱为整数,并且在收到时不会拆箱,因为它应该是和 int,JVM 不会在有参数的情况下拆箱。在第二种情况下,您将原始类型 int 赋予 int 参数,并且第二个参数是自动装箱的。

于 2013-08-03T09:37:39.877 回答
0

您的第二个示例与第二个触发器的签名匹配。第一次调用既不匹配触发器,所以编译器尝试选择最具体的匹配,并且两者都同样具体,因为两者都需要装箱/拆箱才能匹配。由于它们同样适用,因此该调用是模棱两可的。

请参阅 Java 语言规范,第 15.12 条方法调用表达式。

于 2013-08-03T09:51:12.090 回答