为何Late Binding未按预期生效?Java方法调用结果不符预期
问题原因解析
要搞清楚这个结果,得拆分Java方法调用的编译阶段绑定和运行阶段分派两个核心步骤:
1. 编译阶段:确定要调用的方法签名
变量obj的声明类型是A,编译器只会依据A类中定义的方法来做匹配——A里只有一个方法:public int m(C c)。
当你调用obj.m(new E())时,编译器要找A中能适配参数E的方法:因为E是C的子类(E extends D extends C),参数可以向上转型为C,所以编译器会把这个调用绑定到A::m(C)这个方法签名上。注意:子类B或H中定义的m(D)、m(E)等重载方法,在A的方法列表里根本不存在,所以编译阶段完全不会考虑它们。
2. 运行阶段:确定具体执行的方法实现
运行时,实际对象是H,但H并没有重写m(C c)方法——H中的方法参数是I、D、E,都不是C,所以不会覆盖A中的m(C)。这时JVM会沿着继承链向上找最近的重写版本:B类重写了A::m(C)并返回7,所以最终执行的是B::m(C),输出7。
你预期调用H::m(E)的误区在于:忽略了编译阶段的方法绑定规则——编译器只会根据变量的声明类型选择方法,而非实际对象类型。H::m(E)这个方法在A的方法体系里不存在,所以从编译阶段开始就不会被选中。
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

