美文网首页
JVM执行方法调用1

JVM执行方法调用1

作者: Monkey007 | 来源:发表于2019-08-20 10:12 被阅读0次

    方法的重载与重写

    重载:同一个类中出现多个名字相同,并且参数类型不同的方法,这些方法之间的关系,称之为方法重载。

    小知识点:这个限制可以通过字节码工具绕开。也就是说,在编译完成之后,我们可以再向 class 文件中添加方法名和参数类型相同,而返回类型不同的方法。当这种包括多个方法名相同、参数类型相同,而返回类型不同的方法的类,出现在 Java 编译器的用户类路径上时,它是怎么确定需要调用哪个方法的呢?当前版本的 Java 编译器会直接选取第一个方法名以及参数类型匹配的方法。并且,它会根据所选取方法的返回类型来决定可不可以通过编译,以及需不需要进行值转换等。

    重载方法的选取过程,重载方法在编译过程中即可完成始别。可以具体到每一个方法调用,Java编译器会根据所传入参数的声明类型(注意与实际类型区分)来选取重载方法。选取过程分为三个阶段:

    1、在不考虑对基本类型自动装拆箱(auto-boxing,auto-unboxing),以及可变长参数的情况选取重载方法;

    2、如果在第一个阶段中没有找到适配的方法,那么在允许自动装拆箱,但不允许可变长参数的情况下选取重载方法;

    3、如果在第2个阶段中没有找到适配的方法,那么在允许自动装拆箱以及可变长参数的情况下选取重载方法。

    注意:如果Java编译器在同一个阶段找到了多个适配的方法,那么它会在其中选择一个最为贴切的,而决定贴切程度的一个关键就是形式参数类型的继承关系。

    重写:如果子类定义与父类中非私有方法、非静态方法同名的方法,而且这两个方法的参数类型相同,那么这两个方法称之为方法重写。

    Java是一门面向对象的编程语言,它的一个重要特性便是多态,而方法重写,正是多态最重要的一种体现方式:它允许子类在继承父类部分功能的同时,拥有自己独特的行为。

    比如,如果你经常漫游,那么你可能知道,拨打10086会根据你当前所在地,连接到当地的客服。重写调用也是如此:他会根据调用者的动态类型,来选取实际的目标方法。

    JVM的静态绑定和动态绑定

    Java虚拟机是怎么识别方法的?

    Java虚拟机识别方法的关键在于类名、方法名以及方法描述符(method descriptor)。方法描述符,他是由方法的参数类型以及返回类型所构成。在同一个类中,如果同时出现多个名字相同且描述符也相同的方法,那么Java虚拟机会在类的验证阶段报错。

    Java虚拟机与Java语言不同,它并不限制名字与参数类型相同,但返回类型不同的方法出现在同一个类中,对于调用这些方法的字节码来说,由于字节码所附带的方法描述符包含了返回类型,因此Java虚拟机能够准确地识别目标方法。

    Java虚拟机中关于方法重写的判定同样基于方法描述符。也就是说,如果子类定义了与父类中非私有、非静态方法同名的方法,那么只有当这两个方法的参数类型以及返回类型一致,Java虚拟机才会判定为重写。

    对于Java语言中重写而Java虚拟机中非重写的情况,编译器会通过生成桥接方法来实现Java中的重写语义。

    Java虚拟机中静态绑定指的是在解析时便能够直接识别目标方法的情况,而动态绑定则指的是需要在运行过程中根据调用者的动态类型来识别目标方法的情况。

    总的来说,Java字节码中与调用相关的指令共有五种。

    1、invokestatic:用于调用静态方法。

    2、invokespecial:用于调用私有实例方法、构造器,以及使用super关键字调用父类的实例方法或构造器,和所实现接口的默认方法

    3、invokevirtual:用于调用非私有实例方法。

    4、invokeinterface:用于调用接口方法。

    5、invokedynamic:用于调用动态方法。


    出处:《极客时间》 郑雨迪老师的《深入拆解Java虚拟机》

    备注:纯属督促自己复习,梳理每节知识点。如有错误,请多加指出。谢谢

    相关文章

      网友评论

          本文标题:JVM执行方法调用1

          本文链接:https://www.haomeiwen.com/subject/rjeusctx.html