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

Java调用父类被重写方法遇栈溢出,求实现方案及原因

在Java中调用父类被重写的方法(解决StackOverflowError问题)

你的Java代码触发栈溢出,核心原因是Java里所有非private成员方法默认都是动态绑定(等价于C++的虚函数),而C++普通成员函数是静态绑定,这是两者的关键差异。

错误执行流程拆解:

  1. 调用b.doPrint() → 执行B类的doPrint()
  2. B类doPrint()调用this.print() → 因为动态绑定,实际执行B类的print()
  3. B类print()调用super.doPrint() → 执行A类的doPrint()
  4. A类doPrint()里的this.print() → this仍是B类实例,再次触发B类的print()
  5. 循环往复耗尽栈内存,抛出StackOverflowError

而你C++代码里,A::doPrint()调用的是A自身的print()(非虚函数静态绑定),不会触发B类的print(),所以没有循环问题。

修正方案(实现和C++相同逻辑)

方案一:直接调用父类被重写的print()方法

这是最直接的解决方案,在B类的print()里用super.print()直接调用父类的实现,避免循环:

class A {
    public void doPrint() {
        this.print();
    }
    
    public void print() {
        System.out.println("This is A");
    }
}

class B extends A {
    @Override
    public void doPrint() {
        this.print();
    }
    
    @Override
    public void print() {
        // 直接调用父类的print方法,而非父类的doPrint
        super.print(); 
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.doPrint(); // 输出:This is A
    }
}

方案二:模拟C++静态绑定逻辑

如果需要保留类似C++中调用父类doPrint()且仅触发父类print()的逻辑,可以把A类的print()设为private(私有方法无法被重写,强制静态绑定):

class A {
    public void doPrint() {
        // 调用私有print,不会被子类重写
        print();
    }
    
    // 私有方法无法被重写,确保A的doPrint()调用自身实现
    private void print() {
        System.out.println("This is A");
    }
}

class B extends A {
    @Override
    public void doPrint() {
        this.print();
    }
    
    public void print() {
        super.doPrint(); 
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.doPrint(); // 输出:This is A
    }
}

内容的提问来源于stack exchange,提问作者Star-lordX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:45:41