You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

super调用不符合预期:基类方法为何调用派生类重写方法?

Java方法重写中的动态分派问题解析

代码示例

public class A {
    void someMethod() {
        System.out.println("Some method from A");
    }
    void someOtherMethod() {
        System.out.println("Some other method from A");
        this.someMethod();
    }
}

public class B extends A {
    void someMethod() {
        System.out.println("Some method from B");
    }
    void test() {
        System.out.println("Test method from B");
        super.someOtherMethod();
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.test();
    }
}

程序输出

Test method from B
Some other method from A
Some method from B

现象原因

这是Java动态方法分派的核心特性,也是多态的典型表现:当调用实例方法时,JVM会根据当前对象的实际运行时类型(而非引用的声明类型)来决定执行哪个版本的方法。

在你的代码中,someOtherMethod虽通过super.someOtherMethod()触发,但方法执行时的this仍然指向B类的实例。此时this.someMethod()会触发动态分派,优先执行B类中重写的someMethod,而非A类的原始版本。


实现预期效果的方法

如果想让someOtherMethod固定调用A类自身的someMethod,可以用以下几种方式:

1. 将A类的someMethod设为私有

私有方法无法被子类重写,B类中的someMethod会被视为全新方法,与A类的someMethod无关联。此时A类的someOtherMethod调用的就是自身的私有方法:

public class A {
    private void someMethod() { // 修改为私有
        System.out.println("Some method from A");
    }
    void someOtherMethod() {
        System.out.println("Some other method from A");
        this.someMethod();
    }
}

2. 将A类的someMethod标记为final

final方法禁止子类重写,无论对象实际类型是什么,调用的都是A类的someMethod:

public class A {
    final void someMethod() { // 添加final修饰符
        System.out.println("Some method from A");
    }
    void someOtherMethod() {
        System.out.println("Some other method from A");
        this.someMethod();
    }
}

3. 使用私有辅助方法封装核心逻辑

如果需要保留someMethod的可重写性,但希望someOtherMethod固定执行A类的原始逻辑,可以把核心逻辑封装到私有辅助方法中:

public class A {
    void someMethod() {
        originalSomeMethod();
    }
    // 私有辅助方法,封装A类的核心逻辑
    private void originalSomeMethod() {
        System.out.println("Some method from A");
    }
    void someOtherMethod() {
        System.out.println("Some other method from A");
        originalSomeMethod(); // 直接调用私有辅助方法
    }
}

这样即使B类重写了someMethod,someOtherMethod仍然会执行A类的原始逻辑。


内容的提问来源于stack exchange,提问作者user15822443

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:45:25