super与this调用执行时机疑问及Java多态代码输出解析
代码示例
public class Person { public void method1() { System.out.print("Person 1 "); } public void method2() { System.out.print("Person 2 "); } }
public class Student extends Person { public void method1() { System.out.print("Student 1 "); super.method1(); this.method2(); } public void method2() { System.out.print("Student 2 "); } }
public class Undergrad extends Student { /*public void method1() { System.out.print("ahmed"); }*/ public void method2() { System.out.print("Undergrad 2 "); } }
public class main { static void main(){ Person u = new Undergrad(); u.method1(); } }
运行结果与疑问
实际运行输出:Student 1 Person 1 Undergrad 2
原本预期会无限循环打印"Student 1",但实际输出不符,同时有两个疑问:
super.method1()是否在编译时执行?this.method2()是否在运行时执行?原因是什么?
解答
为什么没有无限循环?
你误以为会无限循环,是错把super.method1()当成了调用当前类的method1。实际上super.methodX()的作用就是强制调用父类的方法版本,不会触发子类的重写逻辑。在Student的method1里,super.method1()直接执行Person类的method1,这个方法里没有递归调用Student的method1,自然不会形成循环。
super与this方法调用的时机
super.method1()不是编译时执行:它是运行时执行,但调用的目标方法在编译阶段就已确定。因为super明确指向父类,编译器编译时就锁定了要调用的是父类的method1,不管运行时对象实际是什么子类类型,这个调用目标都不会变。this.method2()是运行时确定调用目标:this指向当前对象的实际运行类型,编译器编译时只能知道this属于Student或其子类,但具体调用哪个类的method2,要等到运行时根据对象的实际类型(这里是Undergrad)来决定——这就是Java的动态绑定机制,非私有实例方法都会触发这个逻辑。
总结:
super调用的方法是静态绑定,编译期确定目标;this调用的非私有方法是动态绑定,运行期确定目标。
内容的提问来源于stack exchange,提问作者ahmed alaa
相关产品推荐
相关产品推荐

