我知道重载是在编译时决定的,但当我尝试在下面运行时,它会给我一些我无法理解的结果
package miscellaneous;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CollectionsOverloading {
public static String classify(Set<?> s) {
return "Set";
}
public static String classify(List<?> s) {
return "List";
}
public static String classify(Collection<?> s) {
return "Collection";
}
public static void main (String args[]) {
Collection<?>[] collections = { new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
for (Collection<?> coll : collections) {
System.out.println(classify(coll));
}
}
}
当我每次运行此代码片段时,我将输出作为“Collection”,这意味着调用带有参数的classify方法作为Collection。
请解释
答案 0 :(得分:4)
由于您调用的classify
方法是静态的,因此您选择在编译时调用哪一个,而不是在运行时调用。
在编译时,编译器发现collections
是Collection
的数组,因此绑定到public static String classify(Collection<?> s)
版本的classify
。
修改:即使这些方法是非静态的,您仍然会发现自overloaded methods are bonded using static binding at compile-time while overridden methods are bonded using dynamic binding at runtime以来被调用的Collection
版本。
答案 1 :(得分:1)
如前所述,重载方法的链接是在编译时完成的。
当您遍历Collection
列表时,编译器只知道当前元素是Collection
的实例,因此它链接到classify(Collection)
方法,然后始终调用该方法。
答案 2 :(得分:0)
becaluse coll是Collection的类型,所以每次调用classify(Collection s)methed。如果你想调用其他methed,你需要转换类型。这是代码:
Collection<?>[] collections = { new HashSet<String>(),new ArrayList<String>(), new HashMap<String, String>().values() };
for (Collection<?> coll : collections) {
if(coll instanceof Set<?>){
System.out.println(classify((Set<?>)coll));
}
else if(coll instanceof List<?>) {
System.out.println(classify((List<?>)coll));
}
else {
System.out.println(classify((Collection<?>)coll));
}
}