从字节码看方法重载与重写

日期:2020-05-14 12:35:18 来源:互联网 编辑:小优 阅读人数:57

在Java中存在重载与重写,面试中经常会出现与之相关的问题,今天从字节码来看看他们的实现。

简单代码

从字节码看方法重载与重写(图1)

其中有继承关系的三个类Animal、Mamml(哺乳动物)Tiger,主要用来实现重写,AssignTest中有三个test方法用来实现重载,大家可以猜猜打印结果!

运行结果

从字节码看方法重载与重写(图2)

根据打印结果可以看到两个test方法执行的都是test(Animal)这个方法,两个name方法却分别执行的Mammal与Tiger的两个类方法,代码比较简单,所以产生的结果也比较直接简单,接下来我们用字节码来分析分析!

方法字节码

从字节码看方法重载与重写(图3)

字节码指令最重要的部分已经用红框圈出,其中第26行与31行为test方法,可以看到方法的参数都是Animal。

可是在35行与38行同样是执行Animal.name方法,那么为什么会与上面不一样呢?这里就要说到invokevirtual这条指令了,invokevirtual指令会找到方法栈顶的第一个元素它所指向对象的实际类型,在这个实际类型中找对应的方法,如果存在就执行,否则继续往上找,直到找到为止,这就叫方法的动态分配。

这这个例子中,虽然编译时表示的是执行Animal的name方法,可是从前面初始化的指令可以看到仍然是初始化具体的类型,所以他执行具体的方法。

综合代码

在AssignTest在加一个父类,实现重载与重写,同时把name方法放到了test方法中,代码如下图:

从字节码看方法重载与重写(图4)

运行的结果为Mammal、animal、Tiger、animal,说明执行的具体方法并没有发生变化,那么直接看字节码如下图:

从字节码看方法重载与重写(图5)

可以看到字节码指定的方法还是AssignSuperTest.test(Animal)方法,不过我们从结果可以知道还是执行的AssignTest.test(Animal)方法,AssignTest.test(Animal)的字节码指令如下图:

从字节码看方法重载与重写(图6)

AssignTest.test(Animal)在编译期并不知道传进来的Animal具体是什么类型,所以只能在运行期才能通过去查找具体的类型执行!

总结

从字节码来说,方法的重载实际上重载的几个方法已经是相互独立的方法,这与我们平时所理解是一致的(方法通过方法名与参数列表区分),而重写则不同,重写的目的是为了实现子类与父类不同的表现,是多态。

以最后一个例子为例,在test方法中执行name,由于Animal具体的类型不知道,所以不知道会执行具体哪个name方法。

所以方法重载是静态的,是编译器行为,是在写代码期或者编译器可以确定执行哪个方法,而方法重写是动态的,是运行期行为,只有在执行期才知道是具体哪个类型来执行方法。

只要理解了上面两句话在面试中遇到这类题就能够轻松解决。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

本文相关词条概念解析:

方法

(1)[method;way;means](2)古指量度方形的法则(3)现指为达到某种目的而采取的途径、步骤、手段等方法的含义较广泛,一般是指为获得某种东西或达到某种目的而采取的手段与行为方式。它在哲学,科学及生活中有着不同的解释与定义。方法和手段是人们成功办事,或管理者实现管理目的的不可缺少的中介要素。方法虽然也被人们称之为活动的手段,但它不是物化了的手段,是人类认识客观世界和改造客观世界应遵循的某种方式、途径和程序的总和。方法的一个同义词是技术,给人的感觉,方法通俗一些,技术高雅一些。

网友评论
相关文章
自中国足协推出降薪倡议之后,传出这个欠薪或减薪风波

自中国足协推出降薪倡议之后,传出这个欠薪或减薪风波

自中国足协推出降薪倡议之后,传出这个欠薪或减薪风波[详情]

不论是B站还是字节跳动,必有一战

不论是B站还是字节跳动,必有一战

不论是B站还是字节跳动,必有一战[详情]

王占海答应和孙雷切磋斗腕,没想到却被铁砂掌孙雷给做到了

王占海答应和孙雷切磋斗腕,没想到却被铁砂掌孙雷给做到了

王占海答应和孙雷切磋斗腕,没想到却被铁砂掌孙雷给做到了[详情]

网站地图    Copyright     2016-2018  资讯网   All rights reserved.