[关闭]
@TryLoveCatch 2022-04-27T01:22:08.000000Z 字数 1043 阅读 617

Java知识体系之多态

Java知识体系


多态

java多态实现原理

基类的引用指向派生类对象,而在具体方法执行的时候,执行的是派生类的方法。

当某个方法被调用时,JVM 首先要查找相应的常量池,得到方法的符号引用,并查找调用类的方法表以确定该方法的直接引用,最后才真正调用该方法。

类调用 (invokestatic) 是在编译时刻就已经确定好具体调用方法的情况,而实例调用 (invokevirtual) 则是在调用的时候才确定具体的调用方法,这就是动态绑定,也是多态要解决的核心问题。

多态相关的主要是方法表,方法表存放在类的类型信息里面。
调用类为A,基类为B,子类为C,那么假设A类生成的指令invokesvirtual #10,那么会在A的常量池(应为 CONSTANT_Methodref_info 类型,可视为方法调用的符号引用)中找到10对应的条目(方法调用的符号引用),然后进一步查看常量池CONSTANT_Class_info,CONSTANT_NameAndType_info ,CONSTANT_Utf8_info),找到调用的是B类的b方法,然后查看B类的方法表,得到b方法的偏移量12,这就是该方法的直接引用了。
然后JVM真正执行方法调用,根据实例方法调用的参数this得到具体的对象,即为C,然后在C的方法表找到偏移量为12的方法,并调用执行。

接口调用

Java 允许一个类实现多个接口,从某种意义上来说相当于多继承,这样同样的方法在基类和派生类的方法表的位置就可能不一样了。这也是 Java 中调用接口方法有其专有的调用指令(invokeinterface)的原因。
JVM 首先查看常量池,确定方法调用的符号引用(名称、返回值等等),然后利用 this 指向的实例得到该实例的方法表,进而搜索方法表来找到合适的方法地址。
因为每次接口调用都要搜索方法表,所以从效率上来说,接口方法的调用总是慢于类方法的调用的。

继承多态&接口多态

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注