为什么在只调用不带参数的sifter()时调用sifter(C [] ... c2)。我认为这里的方法应该是模棱两可的,但是代码正在编译并将输出表示为-41

package abc;

class A {}
class B extends A {}
class C extends B {}

public class ComingThru {
    static String s = "-";
    public static void main(String...a) {
        A[] aa = new A[2];
        B[] ba = new B[2];
        sifter();
        sifter(aa,ba);
        System.out.println(s);
    }

    static void sifter(A[]... a2) {
        s += "1";
    }

    static void sifter(C[]... c2) {
        s += "4";
    }

    static void sifter(B[]... b1) {
        s += "2";
    }
}

最佳答案

引用Java语言规范

Section 15.12.2.4. Phase 3: Identify Applicable Variable Arity Methods,它指出到最后:


  如果找不到适用的可变Arity方法,则发生编译时错误
  发生。
  
  否则,从以下方法中选择最具体的方法(第15.12.2.5节)
  适用的可变对数方法。


现在,在同一页面的正下方看15.12.2.5节,它指出:


  如果多个成员方法都可访问并且适用于
  方法调用,有必要选择一种方法来提供
  运行时方法分派的描述符。 Java编程
  语言使用选择最具体方法的规则。
  
  非正式的直觉是,一种方法比
  如果可以传递第一种方法处理的任何调用,则返回另一个
  没有编译时类型错误的另一个。


因此,它表明所有3个方法声明都适用于sifter();调用。但是,static void sifter(C[]... c2)是最特定的,因为您可以使用相同的输入调用其他两个方法(A []​​ ...和B [] ...),并且不会出现编译错误。

07-24 18:39