【问题标题】:Why method overloading with boxing & widening giving ambiguous error?为什么用装箱和加宽方法重载会产生模棱两可的错误?
【发布时间】:2014-05-26 03:52:12
【问题描述】:
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 文档但可以

有人请通过

逐步解释为什么方法调用会给出模棱两可的错误

本文档中描述的步骤。

【问题讨论】:

    标签: java wrapper overloading


    【解决方案1】:

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

    然后,它检查一个是否比另一个更具体。这要求一种方法的每个参数类型都是另一种方法的相应参数类型的子类型。由于int and Integer are not comparable,调用是模棱两可的。

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

    obj.m(Byte.valueOf(b), 24);
    

    【讨论】:

    • 我认为第一种方法比第二种方法更具体,因为所有可以通过第一种方法的值也可以通过第二种方法。来自文档:如果第一个方法处理的任何调用可以传递给另一个方法而不会出现编译时类型错误,则一个方法比另一个方法更具体。
    • 更具体的规则是一种方法的所有参数类型都是另一种方法的相应参数类型的子类型,而不是传递给一个方法的所有可能值都可以传递给另一个方法。 Integer 不是int 的子类型,但int 也不是Integer 的子类型。
    • 不,原始值仍然具有子类型关系——请参阅我在回答中链接的规范。选择该方法是因为它可以在没有自动装箱的情况下调用,因此其他方法甚至都不会被视为匹配。
    • 所有阶段都允许扩大转换;第二阶段只是允许装箱/拆箱转换。
    • 这一切都在那个规范部分:编译器首先尝试加宽(阶段 1),然后如果失败则加宽加装箱(阶段 2),如果失败则全部三个(阶段 3)。跨度>
    【解决方案2】:

    来自linked的文档

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

    这里什么也没有发生,因为没有任何方法匹配 (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 部分所述。

    如果你遍历所有这些规则,你会发现没有更具体的方法,所以调用是模棱两可的。

    【讨论】:

    • 你怎么能说没有更适用的方法呢?
    • @user3519914 按照§15.12.2.5 中的规则,没有一个比另一个更具体。
    猜你喜欢
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多