首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 多态陷阱:子类调用父类方法,父类内部又调用被覆盖方法的动态绑定行为

     編輯:Java 綜合教學

Java 多态陷阱:super 调用父类方法,父类内部调用被覆盖方法

经典面试题:子类通过 super.method() 调用父类方法,父类方法内部又调用了被子类覆盖的方法,**最终执行的是子类还是父类的版本?**

代码复现

public class SuperClass {
    public void printA() {
        System.out.print("SuperClass-printA");
        printB();  // 内部调用
    }
    public void printB() {
        System.out.print("SuperClass-printB");
    }
}

public class ChildClass extends SuperClass {
    @Override
    public void printA() {
        System.out.print("ChildClass-printA");
        super.printA();  // 显式调用父类
    }
    @Override
    public void printB() {
        System.out.print("ChildClass-printB");
    }

    public static void main(String[] args) {
        ChildClass child = new ChildClass();
        child.printA();
    }
}

运行结果

ChildClass-printASuperClass-printAChildClass-printB

核心结论

父类方法内部调用被覆盖方法时,触发动态绑定,执行子类的覆盖版本。

  • super.printA() 仅固定调用父类的 printA 实现
  • 父类 printA 内部的 printB() 是 **虚方法调用**,运行时根据对象实际类型(ChildClass)分发
  • 这正是多态的本质:**非静态方法调用默认动态绑定**,super 只能锁定直接调用的目标,无法锁定间接调用链

字节码视角

  • super.printA() → invokespecial SuperClass.printA(静态绑定)
  • printB() → invokevirtual SuperClass.printB(动态分发)

避坑指南

  1. 父类方法尽量 **final** 或 **private**,避免被覆盖导致不可控行为
  2. 模板方法模式:父类定义 final 骨架方法,调用 protected abstract 钩子方法,子类实现钩子
  3. 若必须在父类内部调用「固定版本」,可提取 private void printBInternal() 供内部调用

相关参考

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved