Java静态绑定疑问:Person与Student类方法调用场景分析
关于静态绑定与方法重载的问题解答
第一个问题:你的理解是否正确?
先来看你的代码示例:
class Person { talk(Person p) { print("Hi by person."); } } class Student extends Person { talk(Student s) { print("Hi by stud."); } } // 调用逻辑 Person x = new Student(); x.talk(x); // 输出 "Hi by person."
你的结论是正确的,不过可以再把背后的逻辑拆解清楚:
- 这里
Student类的talk(Student s)属于方法重载,而非方法重写(重写要求方法签名完全一致,包括参数类型必须匹配)。 - 方法重载是基于静态绑定的,编译器会根据变量的编译时类型和参数的编译时类型来确定调用哪个方法:
- 变量
x的编译时类型是Person,传入的参数x编译时类型也是Person,所以编译器会匹配Person类中接收Person参数的talk方法,运行时不会切换到Student的重载方法,因此输出"Hi by person."。
- 变量
第二个问题:仅Student类存在talk(Student s)方法时的调用情况
假设调整后的代码是这样的:
class Person { // 没有定义任何talk方法 } class Student extends Person { talk(Student s) { print("Hi by stud."); } } // 调用逻辑 Person x = new Student(); x.talk(x);
这种情况下会直接编译报错,原因如下:
- 在静态绑定阶段,编译器只会关注变量
x的编译时类型Person,会检查Person类中是否存在符合调用签名的talk方法。 - 由于
Person类里完全没有定义talk方法,也找不到能匹配Person类型参数的重载方法,编译器无法确定要调用的方法,因此编译直接失败,根本不会进入运行阶段。
如果是另一种场景:Person类有其他talk重载(比如talk(Object o)),但只有Student有talk(Student s),那么编译器会匹配Person类的talk(Object o)方法,运行时如果Student没有重写这个方法,就会执行Person的实现(如果有的话)。但按照你问题里“仅Student类存在talk(Student s)方法”的描述,更大概率是Person类没有对应方法,最终触发编译错误。
内容的提问来源于stack exchange,提问作者Jush KillaB
相关产品推荐
相关产品推荐

