传递无参数时在Var args参数中出现混淆

时间:2014-01-08 05:48:24

标签: java arguments variadic-functions

为什么在只调用没有参数的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";
    }   
}

2 个答案:

答案 0 :(得分:2)

引用Java语言规范

Section 15.12.2.4. Phase 3: Identify Applicable Variable Arity Methods,它表示最终:

  

如果找不到适用的变量arity方法,则发生编译时错误   发生。

     

否则,从中选择最具体的方法(§15.12.2.5)   适用的变量方法。

现在查看同一页面下面的第15.12.2.5节,它说明:

  

如果多个成员方法都可访问且适用于a   方法调用,有必要选择一个提供   运行时方法调度的描述符。 Java编程   language使用选择最具体方法的规则。

     

非正式的直觉是一种方法更具体   如果可以传递第一个方法处理的任何调用,则为另一个   没有编译时类型错误的另一个。

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

答案 1 :(得分:1)

我认为它与层次结构Level相关,它调用的参数是继承顺序最低的方法。您可以举例说明,如果我们将B替换为C,那么它将使用B[]...b1作为参数。



    package abc;

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

    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";
        }   
    }


现在输出将为-21