有效:在编译时选择要调用的重载。 例如:
class parentsecond{
public int getdouble(int x){ return x*2;}
}
class second extends parentsecond{
public int getdouble(int x){ return x*3;}
}
class third{
public static void calloverload(parentsecond s){
System.out.println(s.getdouble(4));
}
public static void calloverload(second s){
System.out.println(s.getdouble(4));
}
public static void main(String[] args){
third t=new third();
parentsecond s=new second();
t.calloverload(s);
}
}
答案是12。 并且行为也与方法重载方法相同。
因此,在任何一种情况下,调用哪个重载方法的决定是在运行时而不是编译时(它总是'秒'调用的'getdouble')。
因此,“有效Java”中的这个特定项目有一些我没有得到的资格。
请帮助澄清“在编译时解决重载”的含义。
以上与此有何不同:
....
class fourth{
public static String getCollection(Set<?> s){
return "Set";
}
public static String getCollection(Collection<?> c){
return "Collection";
}
public String getiCollection(Set<?> s){
return "Set";
}
public String getiCollection(Collection<?> c){
return "Collection";
}
public static void main(String[] args){
Collection<String> c=new HashSet<String>();
System.out.println(fourth.getCollection(c));
fourth f=new fourth();
System.out.println(f.getiCollection(c));
...
在这种情况下,这个答案总是“收集”而不是实际的运行时类型。
答案 0 :(得分:2)
声明的s
类型是parentsecond
所以当编译器运行代码时,它将分配以parentsecond
作为参数的方法
public static void calloverload(parentsecond s)...
然而,压倒是一个不同的主题。实例s
的实际类型为second
,因此将执行second
的{{1}}方法。这是多态性的一个例子。在java中,多态性是通过late-binding完成的。
JLS声明§8.4.9重载:
参数为getdouble
,其编译时类型为s
。其运行时类型为parentsecond
。
编辑要回答问题的补充,请参阅上面的第1点。没有什么需要在运行时进行评估。编译器在两次调用中都使用编译时类型second
。
答案 1 :(得分:0)
关键不在于编译器无法弄明白;重点是程序员过载会让人感到困惑,因此可能会导致错误。
如果您需要提取JLS以确定哪种方法与您调用它的方式最具体匹配,那么每个查看该代码的维护程序员都必须进行相同的练习。
因此,建议重载应该具有不同数量的参数,或者至少是不可互换的参数类型。
“在编译时解决重载”的特定危险就是这个。假设我有:
void method(List a) { }
void method(Collection a) { }
然后,这两个调用会做不同的事情:
List list = new ArrayList();
method(list);
method((Collection)list);
对于程序员来说,这是非常不直观的(因此令人困惑,因此也是错误的来源)。