【问题标题】:Ambiguous Overloaded method call resolved模棱两可的重载方法调用已解决
【发布时间】:2016-05-08 19:35:15
【问题描述】:

当我调用时,call('a'); 它会输出“char”,这很好,因为 char 原始类型将优先于将其装箱为 Character。

static void call(char i){
    System.out.println("char");
}

static void call(Character i){
    System.out.println("Character");
}

call('a', 'a'); 的调用为何不明确?

static void call(char i, Character j){
    System.out.println("char");
}

static void call(Character i, Character j){
    System.out.println("Character");
}

我的想法是第二个参数编译器必须使用 Boxing,而第一个参数完美匹配是 char 原始类型,因此对 call('a','a'); 的调用可以解析为 call(char i, Character j) 方法。

显然我理解错了,请高人解释一下。

一些解释此类示例的链接会有所帮助。

【问题讨论】:

    标签: java overloading


    【解决方案1】:

    call('a', 'a'); 的调用为何不明确?

    因为为了使(char i, Character j) 重载适用,围绕拳击的规则开始发挥作用 - 并且此时 两个 调用都适用。这是确定方法签名的第二阶段(JLS 15.12.2)

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

    2. 第二阶段(第 15.12.2.3 节)执行重载解决方案,同时允许装箱和拆箱,但仍排除使用可变参数方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。

    所以在第 2 阶段,两种方法都适用,但确定最具体方法 (JLS 15.12.2.5) 的规则不会使任何一种调用都比彼此更具体。这不是“未装箱比装箱更具体”的问题 - 而是“我可以在没有任何装箱的情况下解决这个问题”之前的问题,然后是“我可以用装箱解决这个问题”。

    【讨论】:

    • 如果我理解正确,在 3 条 JLS 规则中,通过应用不考虑装箱和拆箱的第一条规则,调用 call(char i, Character j) 不清楚,因为第一个参数可以是已解决,但第二个参数需要装箱,它超出了第一条规则的范围,并且控制传递到第二条规则,其中考虑了装箱和拆箱,因此在这种情况下调用(字符 i,字符 j)和调用(字符 i,字符 j ) 是适用的,因为无法解决这就是它给出编译错误的原因?请确认我的理解是否正确。谢谢。
    • 我的问题是,在第二条规则中,它是否只是检查所有方法组合并将调用映射到许多方法,这就是它给出错误的原因?我在想,在第二条规则中,它可能会检查 call(char i, Character j) 的第一个参数是否完全匹配,并且第二个参数调用是使用 Boxing 解决的,
    • @Jayesh:是的,它正在进入第 2 阶段,此时两种方法都比另一种更具体。请注意,“更具体”不会查看实际调用 - 一种方法比另一种更具体,或者不是。在这种情况下,两者都不比另一个更具体。
    【解决方案2】:

    答案在JLS 15.12.2 Compile-Time Step 2: Determine Method Signature

    对于带有charCharacter 的第一个call 方法,编译器只需要第一阶段就可以知道要调用哪个方法。在第一阶段,它不会混合盒装类型和原始类型:

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

    但是,在您使用 2 个参数(charCharacter,以及 CharacterCharacter)的调用中,编译器需要进入 第二 阶段以尝试区分它们,并且在那个特定点上,两种方法都有效:

    第二阶段(第 15.12.2.3 节)执行重载解决方案,同时允许装箱和拆箱,但仍排除使用可变参数方法调用。

    【讨论】:

    • 编译器没有进入第三阶段,因为两者都适用于第二阶段。 “第二阶段(第 15.12.2.3 节)在允许装箱和拆箱的同时执行重载解决方案,但仍然排除使用可变的方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。”跨度>
    猜你喜欢
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    相关资源
    最近更新 更多