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

Java动态绑定执行逻辑及父类引用调用子类方法的疑问

关于Java父类引用、动态绑定的核心疑问解答

咱们结合你贴的测试代码,把两个核心问题拆解清楚:

一、父类引用为啥能调用子类重写的方法,却碰不到子类独有的方法?

这是编译期检查和运行期绑定两个阶段共同作用的结果:

  1. 编译阶段:编译器只认「引用变量的类型」,而非它实际指向的对象类型。你的superobj是MySuper类型的引用,所以编译器只会检查MySuper类里有没有声明对应的方法:
    • derivedFunc1():MySuper里根本没这个方法,直接编译报错(也就是你说的“调用失败”);
    • superFunc1():MySuper里明确声明了这个方法,编译直接放行,不管实际指向的是子类对象。
  2. 运行阶段:代码通过编译后,JVM会看「引用实际指向的对象类型」。你的superobj实际指向MyDerived对象,而MyDerived重写了superFunc1(),所以JVM会调用子类的实现——这就是动态绑定的作用。

另外你提到“子类对象不会创建父类对象”,这个结论是对的:子类对象会包含父类的继承成员,但不会生成独立的父类对象。父类引用只是“看到”子类对象中属于父类定义的接口范围,但运行时执行的是子类的具体实现。

二、什么触发JVM执行动态绑定?

动态绑定的触发有明确的条件:

  • 必须是通过引用变量调用实例方法(注意:静态方法、私有方法、final方法、构造方法都不算,这些属于编译期绑定);
  • 并且该方法被子类重写了。

当满足这两个条件时,JVM在运行时会根据引用实际指向的对象类型,查找并执行对应的方法版本。比如你的superobj.superFunc1(),因为superFunc1()是实例方法且被子类重写,所以JVM会在运行时调用MyDerived中的实现。

举个反例:如果MySuper中的superFunc1()用final修饰,子类没法重写,JVM就会直接绑定父类的实现,不会触发动态绑定。


你的测试代码方便对照:

import java.util.*;
import java.text.*;
public class MyLocale {
    public static void main(String[] args) {
        MySuper superobj=new MyDerived();
        superobj.derivedFunc1(); //语句1:编译失败,MySuper无此方法
        superobj.superFunc1(); //语句2:运行时调用MyDerived的superFunc1()
    }
}
class MySuper {
    void superFunc1() {
        System.out.println("Super");
    }
}
class MyDerived extends MySuper{
    void derivedFunc1() {
        System.out.println("Derived");
    }
    void superFunc1() {
        System.out.println("Derived");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:18:44