
在java中,`super.methodname()`用于显式调用父类的被重写方法;而`this.methodname()`或无修饰的`methodname()`始终触发运行时实际对象类型的重写版本,无法绕过动态绑定——这是避免无限递归和实现精确方法调度的关键。
你遇到的 StackOverflowError 根源在于 Java 的动态方法分派(dynamic dispatch)机制:当 B 实例调用 doPrint() 时,由于 B 重写了 print(),this.print()(等价于 print())永远解析为 B.print(),而非 A.print()。而 B.print() 又调用 super.doPrint(),后者再次调用 this.print() —— 形成闭环。
✅ 正确做法是:在子类中使用 super.print() 直接调用父类的 print() 实现,而非通过 super.doPrint() 间接跳转。以下是修正后的可运行代码:
class A {
public void doPrint() {
this.print(); // 调用当前对象的 print()(多态)
}
public void print() {
System.out.println("This is A");
}
}
class B extends A {
@Override
public void doPrint() {
// ✅ 正确:直接委托给父类的 print()
super.print();
// 或者:System.out.println("Custom prefix from B"); super.print();
}
// ❌ 移除重写的 print() 方法,避免循环依赖
// 若必须重写 print(),则需明确区分用途(见下方说明)
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.doPrint(); // 输出: "This is A"
}
}⚠️ 关键注意事项:
- super.print() 是唯一安全调用父类具体实现的方式,它绕过动态绑定,强制执行父类版本;
- super.doPrint() 仍会触发 this.print() 的动态绑定,因此不能用于“跳过子类重写”;
- 若业务逻辑确实需要 B.print() 存在(例如提供增强版打印),则 B.print() 内部应显式调用 super.print(),而非 super.doPrint():
@Override
public void print() {
System.out.print("[B] ");
super.print(); // ✅ 安全:直接复用 A 的 print 实现
}? 总结:Java 不支持 C++ 风格的 A::print() 语法,但 super.method() 提供了同等语义的、类型安全的父类方法调用能力。设计时应遵循“子类重写方法只负责自身逻辑扩展,父类基础行为统一由 super. 显式调用”,即可彻底规避递归陷阱并保持代码清晰性。
立即学习“Java免费学习笔记(深入)”;










