为什么方法重载与拳击&扩大给出模棱两可的错误?

时间:2014-04-11 20:24:47

标签: java wrapper overloading

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

我已阅读此http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2文件,但可以

有人请逐步解释为什么方法调用通过

给出了模棱两可的错误

本文档中描述的步骤。

2 个答案:

答案 0 :(得分:1)

从文档linked

  

第一阶段(§15.12.2.2)在没有的情况下执行重载决策   允许装箱或拆箱转换,或使用变量arity   方法调用。如果在此阶段没有找到适用的方法   然后处理继续到第二阶段。

这里没有任何事情发生,因为没有任何方法匹配(byte, int)而没有装入其中一个参数。

  

第二阶段(§15.12.2.3)执行重载解析   允许装箱和拆箱,但仍然排除使用变量   arity方法调用。如果在此期间未找到适用的方法   阶段然后处理继续到第三阶段。

在此步骤中,如果对参数执行某些装箱,则两种方法都匹配。如果您框byte,则参数匹配

void m(Number n, int i) {   

如果您点击byteint,则参数匹配

void m(Byte b, Integer i) {  

因此有几种方法适用。

  

如果在其中一个方法中确定了几种适用的方法   适用性测试的三个阶段,然后是最具体的一个阶段   选择,如§15.12.2.5部分所述。

如果你完成所有这些规则,你会发现没有更具体的方法,所以这个电话是不明确的。

答案 1 :(得分:1)

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

然后,它检查一个是否比另一个更具体。这要求一个方法的每个参数类型是另一个方法的相应参数类型的子类型。自int and Integer are not comparable起,电话就不明确了。

调用m(整数)和m(整数)通常不明确的原因是在第一阶段"中找到了适当的方法。在链接的规范中,甚至在考虑拳击之前。在这里,您可以通过将呼叫更改为:

来解决歧义
obj.m(Byte.valueOf(b), 24);