动态绑定与静态绑定
这是Java方法调用的2个术语,用来描述Java虚拟机方法调用的2种机制。
6.1 动态绑定 #
方法的名字和参数列表构成了方法的签名。
返回类型并不是方法签名的一部分,因此在覆盖方法时,允许将导出类的方法返回类型定义为基类返回类型的子类型
方法调用时,虚拟机为每个类创建一个方法表,列出所有的方法签名和实际调用的方法,调用方法时按表查找即可,例如方法表可能是这样的:
FinalMethod:
f() -> FinalMethod.f();
g() -> FinalMethod.g();
p() -> FinalMethod.p();
// skip Object method...
FinalMethodExt
f() -> FinalMethodExt.f();
p() -> FinalMethodExt.p();
// skip Object method...
当对象引用o
调用方法时,其过程可归纳为:
- 虚拟机提取
o
的实际类型的方法表 - 在方法表中搜索调用的方法,若有满足,则直接调用
- 若无满足,则在
o
实际类型的父类中搜索调用的方法 - 调用方法或抛出异常
从上面的描述可以看出,继承体系中的方法调用可能出现不同的结果(导出类覆盖和未覆盖基类方法时的差异现象)。
6.2 静态绑定 #
当方法被private
,static
,final
修饰或调用构造器(构造器可看作是static
方法)的时候,编译器即可准确的知道该调用哪个类的哪个方法,这一过程就是静态绑定。