Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么自动装箱在Java中使一些调用变得模棱两可?_Java_Compiler Construction_Overloading_Autoboxing - Fatal编程技术网

为什么自动装箱在Java中使一些调用变得模棱两可?

为什么自动装箱在Java中使一些调用变得模棱两可?,java,compiler-construction,overloading,autoboxing,Java,Compiler Construction,Overloading,Autoboxing,我今天注意到,自动装箱有时会导致方法重载解析的模糊性。最简单的例子如下: public class Test { static void f(Object a, boolean b) {} static void f(Object a, Object b) {} static void m(int a, boolean b) { f(a,b); } } 编译时,会导致以下错误: Test.java:5: reference to f is ambiguous, bot

我今天注意到,自动装箱有时会导致方法重载解析的模糊性。最简单的例子如下:

public class Test {
    static void f(Object a, boolean b) {}
    static void f(Object a, Object b) {}

    static void m(int a, boolean b) { f(a,b); }
}
编译时,会导致以下错误:

Test.java:5: reference to f is ambiguous, both method
    f(java.lang.Object,boolean) in Test and method
    f(java.lang.Object,java.lang.Object) in Test match

static void m(int a, boolean b) { f(a, b); }
                                  ^
此错误的修复非常简单:只需使用显式自动装箱:

static void m(int a, boolean b) { f((Object)a, b); }
按预期正确调用第一个重载

那么,为什么过载解决方案失败了呢?为什么编译器不自动装箱第一个参数,并正常接受第二个参数?为什么我必须明确地请求自动装箱

那么,为什么超负荷解决方案 失败?为什么编译器没有自动运行 第一个参数,并接受 第二个论点正常吗?我为什么这么做 必须请求自动装箱 明确地说

它通常不接受第二个论点。请记住,“布尔”也可以装箱到对象。您也可以显式地将布尔参数强制转换为对象,这样就可以工作了

那么,为什么超负荷解决方案 失败?为什么编译器没有自动运行 第一个参数,并接受 第二个论点正常吗?我为什么这么做 必须请求自动装箱 明确地说

它通常不接受第二个论点。请记住,“布尔”也可以装箱到对象。您也可以显式地将布尔参数强制转换为Object,它也会起作用。

当您说f(a,b)时,编译器不知道应该引用哪个函数

这是因为aint,但f中预期的参数是对象。因此,编译器决定将a转换为对象。现在的问题是,如果a可以转换为对象,那么b也可以

这意味着函数调用可以引用任一定义。这使得通话模棱两可

当您手动将a转换为对象时,编译器只会查找最接近的匹配项,然后引用它

为什么编译器没有选择 通过“执行”可以实现的功能 最小可能数量的 装箱/取消装箱转换“

请参见以下案例:

f(boolean a, Object b)
f(Object a , boolean b)
如果我们调用likef(布尔a,布尔b),它应该选择哪个函数?这是矛盾的,对吗?类似地,当存在大量争论时,这将变得更加复杂。所以编译器选择给你一个警告

由于无法知道程序员真正想要调用哪一个函数,编译器会给出一个错误。

当你说f(a,b)时,编译器会对应该引用哪个函数感到困惑

这是因为aint,但f中预期的参数是对象。因此,编译器决定将a转换为对象。现在的问题是,如果a可以转换为对象,那么b也可以

这意味着函数调用可以引用任一定义。这使得通话模棱两可

当您手动将a转换为对象时,编译器只会查找最接近的匹配项,然后引用它

为什么编译器没有选择 通过“执行”可以实现的功能 最小可能数量的 装箱/取消装箱转换“

请参见以下案例:

f(boolean a, Object b)
f(Object a , boolean b)
如果我们调用likef(布尔a,布尔b),它应该选择哪个函数?这是矛盾的,对吗?类似地,当存在大量争论时,这将变得更加复杂。所以编译器选择给你一个警告

由于没有办法知道程序员真正想要调用哪一个函数,编译器给出了一个错误。

编译器没有自动将第一个参数设为框。一旦这样做了,第二个参数是不明确的,因为它可以被视为布尔或对象


解释自动装箱和选择要调用的方法的规则。编译器首先尝试在不使用任何自动装箱的情况下选择一个方法,因为装箱和取消装箱会带来性能损失。如果在不使用装箱的情况下无法选择任何方法,如本例中所示,则装箱在该方法的所有参数的表上。

编译器确实自动装箱了第一个参数。一旦这样做了,第二个参数是不明确的,因为它可以被视为布尔或对象


解释自动装箱和选择要调用的方法的规则。编译器首先尝试在不使用任何自动装箱的情况下选择一个方法,因为装箱和取消装箱会带来性能损失。如果在不使用装箱的情况下无法选择任何方法(如本例所示),则该方法的所有参数都将使用装箱。

请参阅

cast很有帮助,因为这样就不需要装箱来找到要调用的方法。如果没有强制转换,第二次尝试是允许装箱,然后也可以装箱布尔值

与其让人们猜测,不如有清晰易懂的规格说明会发生什么。

参见

cast很有帮助,因为这样就不需要装箱来找到要调用的方法。如果没有强制转换,第二次尝试是允许装箱,然后也可以装箱布尔值


最好有清晰易懂的规范来说明将发生什么,而不是让人们猜测。

当您将第一个参数转换为对象时,编译器将匹配该方法,而不使用自动装箱(JLS3 15.12.2):

第一阶段(§15.12.2.2)执行 未经允许的过载解决方案 装箱或取消装箱转换,或 变量算术方法的使用 调用。如果没有适用的方法 在这个阶段发现的 处理继续到第二级 阶段

如果你不显式地释放它,它将进入第二阶段,试图找到匹配的冰毒