Java多态的运行期行为由动态绑定决定,JVM根据对象实际类型(而非引用类型)调用被重写的方法;静态方法、private、final方法及构造器无多态性;字段访问不具多态性,始终依据引用类型。

Java中多态的运行期行为决定,核心靠动态绑定(Dynamic Method Dispatch)——也就是JVM在程序运行时,根据对象的实际类型(而非引用类型)来选择调用哪个方法。
方法重写是前提
只有被子类重写(@Override)的实例方法,才参与运行期绑定。静态方法、private方法、final方法、构造器都不具备多态性,它们在编译期就确定了调用目标。
- 父类引用指向子类对象,如:Animal a = new Dog();
- 调用被重写的方法,如:a.sound(); → 实际执行的是Dog.sound(),不是Animal.sound()
- 该决策由JVM在运行时通过对象头中的虚方法表(vtable)查表完成
引用类型只管编译检查,实际类型决定执行逻辑
声明时的类型(左边)仅用于编译期语法校验和方法可见性判断;真正执行哪段代码,取决于new出来的那个对象属于哪个类(右边)。
- Animal a1 = new Cat(); a1.sound(); → 调用Cat版本
- Animal a2 = new Bird(); a2.sound(); → 调用Bird版本
- 哪怕所有变量都是Animal类型,只要背后实例不同,行为就不同
接口多态同样遵循同一机制
接口变量指向实现类对象时,方法调用也走动态绑定。JVM会根据实际对象类型,查找其实现类中对应的方法入口。
立即学习“Java免费学习笔记(深入)”;
- List<String> list = new ArrayList<>();
- list.add("x"); → 运行时调用ArrayList.add(),不是LinkedList或其它实现
- 接口本身不存方法体,但每个实现类都有自己的vtable,JVM照表索骥
注意:字段访问不具多态性
多态只适用于实例方法调用,对字段(成员变量)的访问始终依据引用类型,不会动态切换。
- 若Animal有字段name = "Animal",Dog重写为name = "Dog"
- Animal a = new Dog(); System.out.println(a.name); → 输出"Animal",不是"Dog"
- 要获取子类字段值,必须强制转型或在方法中返回


















