静态绑定在编译期根据声明类型确定调用目标,适用于private、static、final方法、构造器、重载及字段访问;动态绑定在运行时根据实际对象类型确定,仅适用于非private、非static、非final的重写实例方法。

区分 Java 中方法的动态绑定和静态绑定,关键看“调用目标在什么时候确定”:编译时就定死的是静态绑定,运行时才决定的是动态绑定。
看方法是否可被重写(override)
动态绑定只适用于满足三个条件的实例方法:非 private、非 static、非 final,且被子类实际重写。这类方法在运行时根据对象真实类型选择实现。
- 例如:
Animal a = new Dog(); a.sound();→ 调用Dog.sound(),因为sound()是可重写的实例方法 - 反之,
a.sleep()若是static方法,则调用Animal.sleep(),与右边 new 的是什么无关
看调用依据的是声明类型还是实际类型
静态绑定完全依赖变量的声明类型(即等号左边的类型),不关心 new 出来的是谁;动态绑定则取决于变量所指对象的实际类型(即等号右边的类)。
- 声明类型决定字段访问和 static/final/private 方法调用
- 实际类型决定重写后的实例方法执行哪个版本
- 比如
Parent p = new Child(); p.name取的是Parent.name;但p.show()若被重写,则执行Child.show()
看字节码指令类型
编译后,Java 用不同指令体现绑定方式:
立即学习“Java免费学习笔记(深入)”;
-
invokestatic:对应 static 方法 → 静态绑定 -
invokespecial:对应 private、构造器、super 调用 → 静态绑定 -
invokevirtual:对应普通实例方法(含重写)→ 动态绑定 -
invokeinterface:对接口方法 → 动态绑定
记住哪些一定是静态绑定
以下方法调用在编译期就锁定目标,不会因对象变化而改变:
- 所有 static 方法(属于类,不依赖实例)
- 所有 private 方法(不可继承,无重写可能)
- 所有 final 实例方法(可继承但禁止重写)
- 所有构造方法(每个类独立创建实例)
- 所有方法重载(overload)的选择(由参数的编译期类型决定)


















