使用java中的基本类型的变量参数重载时的奇怪行为

显然,我对过载,自动装箱和变量参数的工作方式知之甚少.

因此,只要有原始类型的参与,这个程序就会导致麻烦.

public static void z(int a, Object...objects){
}
public static void z(Object...objects){
}
public static void main(String[] args) {
    z();    // no error
    z(4);   // Compile time Error : Ambiguous

    z2();               // No error
    z2(true, "sadas");  // Error

    // No problem with reference types
    z3();       // No error. String one called
    z3(5);      // No error. Object one called

    z4();       // Error
    z4(4);      // Error
    z4("asdas");    // Working properly
}
public static void z2(boolean b, Object...objects){
}
public static void z2(Object...objects){
}
public static void z3(String...objects){
    System.out.println("String one called");
}
public static void z3(Object...objects){
    System.out.println("Object one called");
}
public static void z4(int...objects){
    System.out.println("int z4 called");
}
public static void z4(Object...objects){
    System.out.println("Object z4 called");
}

谁能解释为什么会发生这种情况?我可以愉快地使用Integer,Boolean而不是int,boolean但非常想知道它背后的内部工作.

最佳答案 如果编译器无法确定应该使用哪个重载方法变体,则不会编译方法调用.

我们以z4为例:

>方法调用z4()适合两种变体的签名.
>方法调用z4(4)也适合两种变体的签名,因为变量可以自动装箱.
>方法调用z4(“asdas”)不明确,因为String不能转换为int.

更新:解决重载方法调用的规则如下:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

如果在同一阶段选择了多个变量,则选择最具体的变量,*但简而言之,z3(String …)比z3(Object …)更具体,而z4(int … )和z4(对象…)同样具体.

*确定这个最具体的变体的规则有点复杂(见here)

点赞