Java 为什么使用boxing方法重载&;模糊错误?

Java 为什么使用boxing方法重载&;模糊错误?,java,wrapper,overloading,Java,Wrapper,Overloading,我读过这份文件,但我能理解 请有人通过以下步骤逐步解释为什么方法调用会给出不明确的错误: 本文档中描述的步骤。来自您需要的文档 第一阶段(§15.12.2.2)执行过载解决,无需 允许装箱或拆箱转换,或使用变量arity 方法调用。如果在此阶段未找到适用的方法 然后处理继续到第二阶段 这里不会发生任何事情,因为如果不装箱其中一个参数,所有方法都不匹配(byte,int) 第二阶段(§15.12.2.3)在 允许装箱和拆箱,但仍然禁止使用变量 arity方法调用。如果在此过程中未找到适用的方法 阶

我读过这份文件,但我能理解

请有人通过以下步骤逐步解释为什么方法调用会给出不明确的错误:


本文档中描述的步骤。

来自您需要的文档

第一阶段(§15.12.2.2)执行过载解决,无需 允许装箱或拆箱转换,或使用变量arity 方法调用。如果在此阶段未找到适用的方法 然后处理继续到第二阶段

这里不会发生任何事情,因为如果不装箱其中一个参数,所有方法都不匹配
(byte,int)

第二阶段(§15.12.2.3)在 允许装箱和拆箱,但仍然禁止使用变量 arity方法调用。如果在此过程中未找到适用的方法 阶段,然后处理继续到第三阶段

在这一步中,如果对参数进行装箱,则两个方法都匹配。如果选择“字节”,则参数匹配

public class Aman {
    void m(Byte b, Integer i) {     // autoboxing, autoboxing

    }
    void m(Number n, int i) {       // autoboxing -> widening, no conversion

    }
    public static void main(String[] args) {
        byte b = 23;
        Aman obj = new Aman();
        obj.m(b, 24);
    }
}
如果将
字节
int
框起来,则参数匹配

void m(Number n, int i) {   
因此,有几种方法是适用的

如果在其中一个过程中确定了几种适用的方法 适用性测试的三个阶段,最具体的是 按照第节的规定选择


如果查看所有这些规则,您会发现没有更具体的方法,因此调用是不明确的。

首先,没有不使用装箱/取消装箱的适用方法签名,因此编译器会查找适用于装箱的所有签名。它发现这两种方法都适用

然后,它检查其中一个是否比另一个更具体。这要求一个方法的每个参数类型都是另一个方法的相应参数类型的子类型。因为,这个电话是不明确的

对m(Integer)和m(int)的调用通常没有歧义的原因是,在考虑装箱之前,在链接规范的“第一阶段”中找到了合适的方法。在这里,您可以通过将调用更改为:

void m(Byte b, Integer i) {  

你怎么能说没有一个方法更适用?@user3519914按照中的规则,没有一个比另一个更具体。我认为第一个方法比第二个更具体,因为所有可以传递第一个方法的值也可以传递第二个方法。从文档中可以看出:如果第一个方法处理的任何调用都可以传递给另一个方法,而没有编译时类型错误,那么一个方法比另一个方法更为具体。更具体的规则是,一个方法的所有参数类型都是另一个方法的相应参数类型的子类型,并不是说传递给一方的所有可能值都可以传递给另一方
Integer
不是
int
的子类型,但
int
也不是
Integer
的子类型。不,基本值仍然具有子类型关系——请参阅我在回答中链接的规范。选择这个方法是因为它可以在没有自动装箱的情况下调用,所以另一个方法甚至从来没有被认为是匹配的;第二个阶段也允许装箱/取消装箱转换。这都在该规范部分:编译器首先尝试加宽(阶段1),如果失败则加宽装箱(阶段2),如果失败则加宽装箱(阶段3)。
obj.m(Byte.valueOf(b), 24);