有来自考试的程序。谁能解释一下"-434“是怎么回事:
class A {}
class B extends A {}
public class ComingThru {
static String s = "-";
public static void main (String[] args) {
A[] aa = new A[2];
B[] ba = new B[2];
sifter(aa);
sifter(ba);
sifter(7);
System.out.print(s);
}
static void sifter(A[]... a2) { s += "1";}
static void sifter(B[]... b1) { s += "2";}
static void sifter(B[] b1) { s += "3";}
static void sifter(Object o) { s += "4";}
}谢谢!
发布于 2012-01-09 03:08:36
您可能知道,当调用带有几组不同参数的方法时,Java将尝试调用最具体的。因此,例如,sifter(Object)方法可以应用于任何对象,但是如果知道该对象是一个B[],则将调用更具体的sifter(B[])方法。
棘手的一点是,为了确保向后兼容性,当Java试图找出要调用的方法时,它首先会查看是否有任何适用于的非varargs方法。只有当没有这样的方法时,它才会考虑varargs选项。
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.2
因此,当使用A[]调用sifter()时,非varargs方法sifter(Object)是适用的,因此编译器甚至不会考虑sifter(A[]...)。
发布于 2012-01-09 03:08:23
编译器使用以下规则解析方法调用:(不提及声明/可见性范围)
1,如果存在精确的签名匹配,则调用解析为该方法。
2a,如果参数是一个基元,它会尝试在没有匹配的情况下对其进行装箱。
2b,如果不存在匹配,它会尝试扩大范围,这意味着它将查找具有实际参数类型的超类型的声明。
3,如果不存在加宽签名匹配,它将尝试匹配varargs。
如果仍然没有匹配,这意味着编译时错误(步骤2a和2b是互斥的)。
基于这些规则:
-由于初始化,调用sifter(aa);解析为Object参数方法,因为编译器首先尝试加宽。sifter(ba);解析为B[]参数方法,因为它是一个精确的签名匹配,然后最后一个再次解析为Object方法,规则是编译器首先尝试加宽,然后尝试可变参数。因此,方法调用的最终结果是434。
发布于 2012-01-09 03:25:30
你可能认为答案是-134。但实际上是-434。
最后一个"4“来自参数"7”,它只对应于带有对象参数的参数。
"3“对应于直接静态空筛子(B[] b1)。
第一个"4“的原因是最近的参数是Object,因为"(A[]... a2)”无效。如果是"(A... a2)",那么-134应该是正确的。
https://stackoverflow.com/questions/8780235
复制相似问题