Java多态原理

参考

虚方法

  • JVM杂记:对多态实现原理、虚方法表、虚方法、静态解析、动态链接的一些思考_多态和方法表的关系-CSDN博客

静态分派与动态分派

  • (JVM)Java虚拟机:静态分派 & 动态分派 原理解析 - 掘金

虚方法表

  • JVM 栈帧,静态、动态分派以及虚方法表 - 掘金

背景知识

1、静态类型与动态类型

例子

Human a = new Man()

a = new Woman()

静态类型:

变量a的静态类型 = 引用类型 = Human:不会被改变、在编译器可知

动态类型:

变量a的动态类型 = 实例对象类型 = Man:会变化、在运行期才可知

2、虚方法与非虚方法

概念

非虚方法:如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法。静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法

虚方法:其他方法就叫做非虚方法

理解

不能被重写的方法都是非虚方法

3、静态分派与动态分派

静态分派

概念

根据对象的静态类型来进行分配,即根据变量的静态类型确定执行哪个方法

理解

1、非虚方法的执行都是静态分派

2、在编译成字节码文件的时候,就已经确定调用哪个方法了,所以由编译器来确定

字节码文件中就已经说明了是哪个类的方法,分号后面的就是

3、类加载的时候,在解析阶段符号引用就可以直接转化为直接引用

方法重载

说明

方法重载虽然也用到了虚方法,而且指令也是虚方法指令,但他是静态分派

概念

方法重载(OverLoad) = 静态分派 = 根据 变量 的静态类型 确定执行(重载)哪个方法

细节

类型强转

类型强转实际上是创建一个新对象,而不是修改原有的对象

例子

Person a = new Person()

(Man) a

此时会创建一个新的静态类型为Man的对象。

动态分派

概念

根据对象的动态类型来进行分配

理解

1、使用到多态的地方(使用虚方法 ,方法重载的情况除外)就是动态分派

2、在编译的时候,无法确定是要调用哪个类的方法,只有在运行的时候才能确定,由JVM来确定

3、类加载的时候,在解析阶段无法转化为直接引用,只有在运行时才能解析

方法重写原理

1、运行时调用到虚方法的时候,会去找动态类型,而不是静态类型

2、然后把符号引用转化为直接引用

4、虚方法表

概念

每个类都有一个虚方法表,这个放在方法区中,记录了当前这个类重写的方法,如果没有重写父类的方法,虚方法表中不会记录

Java多态原理_第1张图片

背景

当动态分派进行符号引用的转换时,需要去找到实际上需要使用的方法,假如没有重写那么就是调用父类的方法,所以这个判断流程就是使用虚方法表来实现的

作用

加快动态分派时候,符号引用转化为动态引用的过程

流程

1、找到动态类型,查他的虚方法表,有无目标方法

        1、有,那就是这个

        2、没有,查找他的父类

2、如此循环

理解

多态是实际上就是动态分派

你可能感兴趣的:(java,开发语言)