SCJP问题:使用var-args重载Java方法。理由是什么?

时间:2010-02-23 21:18:28

标签: java variadic-functions overloading scjp

为什么以下程序会抛出异常?

public class MainClass{
  public static void main(String[] argv){
       callMethod(2);
  }
  public static void callMethod(Integer... i){
       System.out.println("Wrapper");
  }
  public static void callMethod(int... i){
       System.out.println("Primitive");
  }

}

方法callMethod(Integer [])对于类型MainClass

是不明确的

好的,我可以看到这两种方法中的任何一种都可以工作(如果另一种方法被注释掉),但我也知道如果一个原语与输入的类型不完全匹配,会发生什么样的层次结构。一种方法。

首先尝试的是扩大原语。所以,如果有第三种方法:

      public static void callMethod(long i){
       System.out.println("long");
      }

代码会打印

第二件事是封装原语。因此,如果有一个方法采用整数,那将是调用的方法。

第三个优先事项是var-args。

基于上述优先顺序,我希望第二种情况就是这样。我希望将int包装成一个Integer并调用(Integer ...)。但当然这不会发生。相反,抛出了异常。

有没有人看到并可以解释为什么在此示例中优先级不适用?

干杯!

1 个答案:

答案 0 :(得分:9)

你是正确的,在拳击之前进行扩大,然后在变速之前。

但您似乎将第一种方法视为callMethod(Integer i),而不是callMethod(Integer... i)。由于两种方法都使用var-args,因此优先级为 tie 。也就是说,两者都不符合拳击的标准,但都符合var-args的标准。

请记住,加宽是非法的,然后是盒子(虽然我在发布这个答案之前做了一些研究,发现它是合法的,然后加宽)。同样,你不会得到盒子,然后是var-args行为;编译器直接跳转到var-args步骤,并看到两个采用var-args的方法。

编辑:我应该澄清,如果没有歧义,你会得到box-then-var-args行为。换句话说,如果只有一个callMethod(),并且花了Integer... i,那么您将获得“Wrapper。”