Java方法调用

方法调用,分为两种。解析调用和分派调用。

解析调用

方法调用的任务不是方法执行,而仅仅是确定,要调用的方法的版本。

第一种是在类加载时候的解析阶段就能够确定方法调用的版本的,这种情况被称作是“解析”

第二种是在运行时候才能确定调用方法的版本,这成为“动态分派”。

先说说第一种,“解析”

能够在类加载的解析阶段就确定调用版本的,有两种函数,第一是private函数,第二是静态方法。这两种函数都不可能被继承或者是重写,所以适合在加载阶段进行解析。解析过程是一个静态的过程,在类加载的时候直接把符号引用转换为直接引用。

分派调用

分派调用可能是静态的,也可能是动态的。

静态分派

“重载”函数,它的分派调用就是静态的。【个人感觉,静态分派是针对重载来说的。比如说同一个类中有多个同名函数,但是参数不同。比如,一个函数的参数是父类,另外有两个其他函数的参数是子类。此时,如果调用函数,那么传进来的参数的静态类型决定了要调用的是哪个函数】

父类 a=new 子类

上面一行代码中,a是变量的静态类型,new出来的对象是对象的实际类型,在重载函数的调用过程中,是根据变量的静态类型来确定调用版本的。所以这里如果用aVariable.test(a)来调用函数的话,那调用的会是以父类为参数test函数。

动态分派

【动态分派技术个人认为是针对“覆盖”父类的方法而言的。使用父类引用引用了子类的对象。那么在调用函数的时候,如果子类覆盖了父类的方法,那么调用的就是子类的方法。否则调用父类的方法】

动态分派是面向对象语言的精髓。在运行时动态确定调用方法的版本。动态分派涉及到一个“多态查找的过程

父类 a=new 子类

在调用a.test()函数的时候,是根据“实际类型”来确定调用的函数的,那么在调用test函数的时候,a的实际类型是子类,那么就会去调用子类中“重写”的test函数,如果发现子类中没有重写test函数,那么就向上查找父类,调用父类中的test函数。

虚拟机在执行函数调用的时候,如果每次都进行这样的“多态查找”,那么性能就可想而知了。由于动态分派是非常频繁的动作,所以虚拟机在实现的时候,常用的优化方法是,在类的方法区中建立一个“虚方法表”,虚方法表中存放了各个函数的实际入口地址。如果某一个方法在子类中进行了重写,那么子类的这个地址就是自己的方法的地址,如果子类没有重写,那么子类方法的地址就也指向父类方法的地址【即父类和子类共用一个函数】。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值