use*_*594 17 java overloading dynamic-binding
在下面的代码中,第一个和第二个打印语句如何打印出SubObj?顶部和子指向同一个Sub类吗?
class Top {
public String f(Object o) {return "Top";}
}
class Sub extends Top {
public String f(String s) {return "Sub";}
public String f(Object o) {return "SubObj";}
}
public class Test {
public static void main(String[] args) {
Sub sub = new Sub();
Top top = sub;
String str = "Something";
Object obj = str;
System.out.println(top.f(obj));
System.out.println(top.f(str));
System.out.println(sub.f(obj));
System.out.println(sub.f(str));
}
}
Run Code Online (Sandbox Code Playgroud)
以上代码返回以下结果.
SubObj
SubObj
SubObj
Sub
Run Code Online (Sandbox Code Playgroud)
Aar*_*han 13
既然您已经了解了案例1,3和4,那么让我们解决案例2.
(请注意 - 我绝不是JVM或编译器内部工作方面的专家,但这是我理解它的方式.如果有人读这篇文章是JVM专家,请随时编辑这个答案,你可能会发现任何差异.)
子类中具有相同名称但签名不同的方法称为方法重载.方法重载使用静态绑定,这基本上意味着在编译时强制适当的方法被"选择"(即绑定).编译器不知道对象的运行时类型(也就是实际类型).所以当你写:
// Reference Type // Actual Type
Sub sub = new Sub(); // Sub Sub
Top top = sub; // Top Sub
Run Code Online (Sandbox Code Playgroud)
编译器只"知道"top是Top类型(也就是引用类型).所以当你后来写:
System.out.println(top.f(str)); // Prints "subobj"
Run Code Online (Sandbox Code Playgroud)
编译器"看到"调用'top.f'作为引用Top类的f方法.它"知道"str是String类型,它扩展了Object.因此,1)调用'top.f'引用Top类的f方法,2)类Top中没有f方法接受String参数,3)因为str是Object的子类,Top类的f方法是编译时唯一有效的选择.因此编译器隐式地将str向上转换为其父类型Object,因此可以将其传递给Top的f方法.(这与动态绑定形成对比,其中上述代码行的类型解析将推迟到运行时,由JVM而不是编译器解析.)
然后在运行时,在上面的代码行中,top被JVM向下转换为它的实际类型sub.但是,参数str已由编译器向上转换为Object类型.所以现在JVM必须在class sub中调用一个带有Object类型参数的f方法.
因此,上面的代码行打印"subobj"而不是"sub".
有关另一个非常类似的示例,请参阅:Java动态绑定和方法覆盖
更新:发现这篇关于JVM内部工作原理的详细文章:
http://www.artima.com/underthehood/invocationP.html
我评论了你的代码,以便更清楚地了解发生了什么:
class Top {
public String f(Object o) {return "Top";}
}
class Sub extends Top {
public String f(String s) {return "Sub";} // Overloading = No dynamic binding
public String f(Object o) {return "SubObj";} // Overriding = Dynamic binding
}
public class Test {
public static void main(String[] args) {
// Reference Type Actual Type
Sub sub = new Sub(); // Sub Sub
Top top = sub; // Top Sub
String str = "Something"; // String String
Object obj = str; // Object String
// At Compile-Time: At Run-Time:
// Dynamic Binding
System.out.println(top.f(obj)); // Top.f (Object) --> Sub.f (Object)
// Dynamic Binding
System.out.println(top.f(str)); // Top.f (Object) --> Sub.f (Object)
// Static Binding
System.out.println(sub.f(obj)); // Sub.f (Object) Sub.f (Object)
// Static Binding
System.out.println(sub.f(str)); // Sub.f (String) Sub.f (String)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6500 次 |
| 最近记录: |