
在java中,`this.print()`始终调用运行时对象的实际类型所对应的重写方法,无法直接通过`this`访问当前类声明的版本;若需调用父类中被重写的同名方法,必须显式使用`super.print()`——但仅限于**直接父类的同名方法**,且不能用于间接调用父类的其他方法(如`super.doprint()`中又调用`this.print()`仍会触发重写)。
你遇到的 StackOverflowError 根本原因在于 Java 的动态绑定(Dynamic Method Dispatch)机制:this.print() 永远解析为当前对象实际类型的 print() 实现,而非声明类型的。在你的示例中:
- B b = new B(); b.doPrint(); → 调用 B.doPrint()
- B.doPrint() 中执行 this.print() → 由于 this 是 B 实例,调用 B.print()
- B.print() 中执行 super.doPrint() → 调用 A.doPrint()
- A.doPrint() 中执行 this.print() → 再次调用 B.print()(因为 this 仍是 B 实例)
从而形成无限递归:B.print() → A.doPrint() → B.print() → …
✅ 正确解法:若目标是让 B.print() 行为等价于 “执行 A 类原始的 print() 输出”,应直接委托给 super.print(),而非通过 super.doPrint() 间接调用:
class A {
public void doPrint() {
this.print(); // 动态绑定:对 B 实例即调用 B.print()
}
public void print() {
System.out.println("This is A");
}
}
class B extends A {
@Override
public void doPrint() {
this.print(); // 同样动态绑定 → B.print()
}
@Override
public void print() {
super.print(); // ✅ 关键修正:直接调用 A.print(),不经过 doPrint
}
}运行结果:
本文档主要讲述的是Android中JNI编程的那些事儿;JNI译为Java本地接口。它允许Java代码和其他语言编写的代码进行交互。在android中提供JNI的方式,让Java程序可以调用C语言程序。android中很多Java类都具有native接口,这些接口由本地实现,然后注册到系统中。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“Java免费学习笔记(深入)”;
This is A
⚠️ 注意事项:
- super.xxx() 只能调用直接父类中定义的方法(或字段),不能跳过父类调用祖父类;
- super 不能用于静态上下文(如静态方法)、构造器外的 this 引用,也不能在 static 方法中使用;
- 若需更灵活的控制流(例如 B 中想复用 A 的 doPrint 逻辑但绕过其 print() 重写),应重构设计:将可变行为抽取为模板方法(Template Method Pattern),例如:
class A {
public final void doPrint() { // final 防止子类覆盖流程
printImpl();
}
protected void printImpl() {
System.out.println("This is A");
}
}
class B extends A {
@Override
protected void printImpl() {
System.out.println("This is B");
}
}这种设计明确分离了“算法骨架”与“可变行为”,避免了调用链歧义,是 Java 中更健壮、符合面向对象原则的实践方式。









