JVM 方法的调用

方法的调用

在JVM中,将符号引用转换为调用方法的直接引用与方法的绑定机制有关。

  • 静态链接:
    • 当一个字节码文件被转载进JVM内部时,如果被调用的目标方法在编译器可知,且运行期保持不变时,这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。
  • 动态链接
    • 如果被调用的方法在编译期间无法被确定下来,也就是说,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也被称之为动态链接。

对应的方法的绑定机制为:早期绑定(Early Binding) 和晚期绑定(Late Binding)。 绑定是一个字段,方法,或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。

  • 早期绑定:
    • 早期绑定就是指被调用的目标方法如果在编译期可知,且运行期保持不变时,即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号引用转换为直接引用。
  • 晚期绑定:
    • 如果被调用的方法在编译期间无法被确定下来,只能够在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称之为晚期绑定。
方法的调用: 虚方法和非虚方法
  • 非虚方法:
    • 如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法
    • 静态方法,私有方法,final 方法 , 实例构造器,父类方法都是非虚方法
    • 其他方法成为虚方法

子类对象的多态性的使用前提: ①类的继承关系 ②方法的重写

虚拟机中提供了以下几条方法调用指令:

  • 普通调用指令:
    • invokestatic: 调用静态方法,解析阶段确定唯一方法版本
    • invokespecial: 调用方法, 私有及父类方法,解析阶段确定唯一方法版本
    • invokevirtual:调用所有虚方法
    • invokeinterface: 调用接口方法
  • 动态调用指令:
    • invokedynamic: 动态解析出需要调用的方法, 然后执行。
      前四条指令固化在虚拟机内部,方法的调用执行不可认为干预,而invokedynamic指令则支持有用户确定方法版本,其中invokestatic指令和invokespecial指令调用的方法称为非虚方法,其余的 (final 修饰的除外) 称为虚方法
方法的调用:关于invokedynamic 指令
  • JVM字节码指令集一直比较稳定,知道JAVA7中才增加了一个invokedynamic指令,这是JAVA为了实现[动态类型语言]支持而做的一种改进
  • 但是JAVA7中并没有提供直接生成invokedynamic指令,知道Java8的Lambda 表达式的出现,invokedynamic指令的生成,在JAVA中才有了直接的生成方式。
  • Java7 中增加的动态语言类型支持的本质是对Java虚拟机规范的修改, 而不是对Java 语言规则的修改,这一块相对来讲比较复杂,增加了虚拟机中的方法调用, 最直接的受益者就是运行在Java 平台的动态语言的编译器。
方法的调用:方法重写的本质

Java 语言中方法重写的本质

  1. 找到操作数栈顶的第一个元素所执行的对象的实际类型, 记作C
  2. 如果在类型C中找到与常量中描述符合简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束; 如果不通过,则返回java.lang.IllegalAccessError 异常。
  3. 否则,则按继承关系从下往上找依次对C的各个父类进行第2步的搜索和验证。
  4. 如果始终没有找到合适的方法,则抛出 java.lang.AbstractMethodError 异常

IllegalAccessError 介绍:
程序试图访问或修改一个属性或调用一个方法, 这个属性或方法,你没有权限访问。 一般的,这个会引起编译器异常。这个错误如果放生在运行时, 就说明了一个类发生了不兼容的改变。

方法的调用:虚方法表
  • 在面向对象的编程中,会很频繁的使用到动态分派,如果在每次动态分派的过程中都要重新在类的方法元数据中搜索合适的目标的话就可能影响到执行效率,因此,为了提高性能, JVM 采用在类的方法区建立一个虚放发表(virtual method table) (非虚方法不会出现在表中)来实现,使用索引表来代替查找。
  • 每一个类中都有一个虚方法表,每个表中存在各个方法的实际入口
  • 那么虚方法表什么时候被创建呢?
    • 虚方法表会在类加载的链接阶段被创建并开始初始化,类的变量初始值准备完成后,JVM 会把该类的放发表也初始化完毕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值