为什么以下程序会抛出异常?
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 ...)。但当然这不会发生。相反,抛出了异常。
有没有人看到并可以解释为什么在此示例中优先级不适用?
干杯!
答案 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
。”