模糊重载方法调用已解决

时间:2016-05-08 11:11:46

标签: java overloading

当我打电话时,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)方法。

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

解释特定此类示例的某些链接将会有所帮助。

2 个答案:

答案 0 :(得分:5)

  

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

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

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

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

  4.   

因此,在第2阶段,两种方法都适用,但确定最具体方法(JLS 15.12.2.5)的规则不会使任何一种调用更具体。这不是“未装箱比盒装更具体”的问题 - 这是“我可以解决这个没有任何拳击”的问题“我可以用拳击解决这个问题。”

答案 1 :(得分:4)

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

对于callchar的第一个Character方法,编译器只需要第一个阶段即可知道要调用哪个方法。在第一阶段,它不是混合盒装和原始类型:

  

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

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

  

第二阶段(§15.12.2.3)在允许装箱和拆箱的同时执行重载解析,但仍然排除使用变量arity方法调用。