> 文章列表 > Java核心技术知识点笔记—理解方法调用

Java核心技术知识点笔记—理解方法调用

Java核心技术知识点笔记—理解方法调用

前言:方法和方法调用是Java编程中的基础,理解方法调用的过程非常重要。本文做一个简单的记录。

假设有一个名为TestA的类,类中有名为f(args)的方法若干(依据方法重载特性,可以有f(int)、f(String)等名称相同,参数类型不同的同名方法)。现在要对TestA类的一个实例c应用方法f(args)的调用,下面是详细的调用过程:

1、编译器查看对象的声明类型和方法名。如上所述,可能存在多个同名而不同参数类型的方法,编译器将会逐个列举出TestA类中所有名为f(args)的方法,以及其超类(如果有)中访问权限为public的名为f(args)的方法(超类的私有方法不可访问)。至此,编译器获得所有可能被调用的候选方法。

2、编译器查看调用方法时提供的参数类型。如果存在与提供的参数类型完全匹配的方法f(args),就选择这个方法。(这个过程被称为重载解析(overloading resolution)。由于允许类型转换(如int可以转换成double),此过程可能很复杂。)。如果没有找到与参数类型匹配的方法,或者发现经过类型转换后有多个方法匹配,则会报告一个错误。至此,编译器获得需要调用的方法的名字和参数类型。

3、如果是private方法、static方法、final方法或者构造器,编译器将可以准确地知道应该调用哪个方法,这种调用方式称为静态绑定(static binding)。与此对应的,调用方法依赖于对象实例的实际类型(如本例中的实例c),且在运行时实现动态绑定。本例中,编译器将采用动态绑定的方式生成一条调用f(args)的调用指令。

4、当程序运行,并且采用动态绑定方式调用方法时,虚拟机调用与实例c所引用对象的实际类型最符合的那个类的方法。例如,c的实际类型是TestA类,如果TestA类中有符合条件的方法f(args),则直接调用该方法,如果没有,则在TestA的超类(如果有)中寻找符合条件的方法,以此类推。

5、由于方法调用时所需进行的搜索操作时间开销相当大,因此,虚拟机预先为每个类创建了一个方法表(method table),其中列出了所有方法的签名和实际调用的方法。如此,在真正调用方法时,虚拟机仅需查找这个表。