Java动态绑定执行逻辑及父类引用调用子类方法的疑问
关于Java父类引用、动态绑定的核心疑问解答
咱们结合你贴的测试代码,把两个核心问题拆解清楚:
一、父类引用为啥能调用子类重写的方法,却碰不到子类独有的方法?
这是编译期检查和运行期绑定两个阶段共同作用的结果:
- 编译阶段:编译器只认「引用变量的类型」,而非它实际指向的对象类型。你的
superobj是MySuper类型的引用,所以编译器只会检查MySuper类里有没有声明对应的方法:derivedFunc1():MySuper里根本没这个方法,直接编译报错(也就是你说的“调用失败”);superFunc1():MySuper里明确声明了这个方法,编译直接放行,不管实际指向的是子类对象。
- 运行阶段:代码通过编译后,JVM会看「引用实际指向的对象类型」。你的
superobj实际指向MyDerived对象,而MyDerived重写了superFunc1(),所以JVM会调用子类的实现——这就是动态绑定的作用。
另外你提到“子类对象不会创建父类对象”,这个结论是对的:子类对象会包含父类的继承成员,但不会生成独立的父类对象。父类引用只是“看到”子类对象中属于父类定义的接口范围,但运行时执行的是子类的具体实现。
二、什么触发JVM执行动态绑定?
动态绑定的触发有明确的条件:
- 必须是通过引用变量调用实例方法(注意:静态方法、私有方法、final方法、构造方法都不算,这些属于编译期绑定);
- 并且该方法被子类重写了。
当满足这两个条件时,JVM在运行时会根据引用实际指向的对象类型,查找并执行对应的方法版本。比如你的superobj.superFunc1(),因为superFunc1()是实例方法且被子类重写,所以JVM会在运行时调用MyDerived中的实现。
举个反例:如果MySuper中的superFunc1()用final修饰,子类没法重写,JVM就会直接绑定父类的实现,不会触发动态绑定。
你的测试代码方便对照:
import java.util.*; import java.text.*; public class MyLocale { public static void main(String[] args) { MySuper superobj=new MyDerived(); superobj.derivedFunc1(); //语句1:编译失败,MySuper无此方法 superobj.superFunc1(); //语句2:运行时调用MyDerived的superFunc1() } } class MySuper { void superFunc1() { System.out.println("Super"); } } class MyDerived extends MySuper{ void derivedFunc1() { System.out.println("Derived"); } void superFunc1() { System.out.println("Derived"); } }
内容的提问来源于stack exchange,提问作者sql_dummy
相关产品推荐
相关产品推荐

