重载和重写在JVM中如何实现的?

简介: 重载和重写在JVM中如何实现的?

正文


Java的三大特性,即封装、继承、多态。最能体现重载和重新的特征是在三大特性中的多态体现的。而在多态的实现的过程中,分派的调用过程是Java多态的特征的一些基本的体现。下面简单的说明一下什么是静态分派和动态分派。


静态分派:所有依赖静态类型来决定执行版本的分派为静态分派。

下面看一个例子:


10.png执行的结果如下:

14.png

Human man = new Man(); 这行代码中Human称为变量的静态类型,

或者是外观类型。

后面的Man类型称为实际类型或者叫做运行时类型。

静态类型和实际类型在程序中都有可能发生变化。区别是静态类型的变化仅仅发生在使用的时候,变量自身的静态类型是不会发生变化的,并且最终的静态类型是在编译期间是可以知道的。而实际类型是在运行期间才能确定,编译器在编译期间是不知道一个对象的类型是什么的。而静态分派就是根据静态类型来执行的,静态分派最典型的代表就是方法重载。

静态分派发生在编译阶段,因此静态分派动作实际上不是由虚拟机来执行的。


动态分派:它是Java语言多态性的另一种体现--方法重写

13.png

运行结果如下:

12.png

从上面运行的结果可以看出,调用方法的选择不可能再根据静态类型来决定的,因为静态类型同样都是Human的类型。导致运行结果不一样是因为实际类型的不同,那么JVM是通过什么样的方式通过实际类型找到执行版本的呢?我们下面的图片:

11.png


可以看到,实际上采用的是invokevirtual字节码命令来实现的,而invokevirtual这个命令是在运行期间确定接收者的实际类型,所以两次调用的结果是不同的。也就是说重写的本质是:在运行期间,JVM采用invokevirtual的命令确定接受者的实际类型,而在解析常量池中到方法引用后,还要根据接受者的实际类型选择方法的版本。

把这种在运行期间根据实际类型确定执行方法的版本的分派过程称为动态分派。



单分派和多分派:静态分派属于多分派类型,而动态分派属于单分派。所以java语言是静态多分派,动态单分派的语言。

重载是静态多分派实现的,重写是动态单分派实现的。

相关文章
|
2月前
|
Java 编译器
重载和重写的区别是什么?
重载和重写的区别是什么?
|
2月前
重载和重写的区别
重载和重写的区别
12 0
|
4月前
|
C++
面试题:重写和重载的区别
面试题:重写和重载的区别
14 0
|
10月前
重载和重写有什么区别?
重载和重写有什么区别?
46 0
|
5月前
|
存储 缓存 Java
认真学习JVM的方法调用(方法重载和重写)
认真学习JVM的方法调用(方法重载和重写)
22 0
|
5月前
|
Java 编译器
详解Java中的重写和重载 | 动态绑定和静态绑定
详解Java中的重写和重载 | 动态绑定和静态绑定
95 0
|
5月前
|
Java 编译器
八股文-Java方法的重载与重写
在 Java 中,重载和重写是两个关键的面向对象编程概念。重载通过方法的参数列表不同来区分同名方法,提供了更灵活的方法调用方式。而重写通过子类重新定义父类中已经存在的方法,实现了多态性的体现,让代码更具可扩展性和维护性。
82 2
八股文-Java方法的重载与重写
|
Java 编译器
java方法的重载要求与作用,重载与重写的区别
java方法的重载要求与作用,重载与重写的区别
234 0
什么是重载、重写,重载和重写的区别是什么?
什么是重载、重写,重载和重写的区别是什么?
89 2
什么是重载、重写,重载和重写的区别是什么?
|
机器学习/深度学习 Java
Java方法重写的注意事项
需要特别说明“无修饰符”这个情况,子类能否访问父类中无修饰符的变量/方法,取决于子类的位置。如果子类和父类在同一个包中,那么子类可以访问父类中的无修饰符的变量/方法,否则不行。
65 0