关于java方法调用过程的理解:
前提:有两个类,分别为
A
和B
(B
继承自A
,即A
为B
的超类,B
为A
的子类),对象x
声明为B
的一个对象,假设调用x.fun(params)
1、编译器查看对象的方法名和声明类型。
获取所有可能被调用的方法:类中可能会存在很多名为
fun
但参数类型不一样的方法。编译器会列举B
类中所有名为fun
和超类A
中访问属性为public
且名为fun
的方法。
2、编译器查看调用方法时提供的参数类型。
找出最合适被调用的那个方法:当在所有名为
fun
的方法中存在一个与提供的参数类型完全匹配的方法,那么就选择这个。
注意:如果编译器没有找到与参数类型匹配的方法,或者经过类型转换后发现有多个方法与之匹配的话,就会报错
3、静态绑定
:如果是private
、static
、final
或者构造器方法,则编译器可以准确的知道应该调用哪个方法。动态绑定
:调用的方法依赖于隐式参数的实际类型,并且在运行时实现动态绑定。
4、程序运行时,并且采用动态绑定调用方法,虚拟机一定调用与x所引用对象的实际类型最合适的那个类的方法。如x的实际类型是B
,B
又是A
的子类,那么如果B
定义了方法fun(params)
,就直接调动它,否则在超类A
中寻找fun(params)
,以此类推。
由于每次调用方法都进行搜索,开销是比较大的,所以虚拟机会预先为每个类创建一个
方法表
,这个方法表中列出了所有方法的签名(方法签名:包括方法名和参数
)和实际调用的方法。这样在调用方法的时候,直接查表就可以了。
内容参考书籍:“Java核心技术 卷1”
网友评论