显然,我对重载、自动装箱和可变参数的工作原理还不够了解。

因此,只要涉及原始类型,这里的程序就会引起麻烦。

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

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

    如果在同一阶段选择了多个变体,则选择最具体的一个,*但简而言之 z3(String...)z3(Object...) 更具体,而 z4(int...)z4(Object...) 同样具体。
    *确定这个最具体变体的规则有些复杂(参见 here )

    关于java - 在java中使用原始类型的变量参数重载时的奇怪行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42782447/

    10-10 11:42