《深入理解 Java 虚拟机》阅读笔记2系列:方法调用

本文详细探讨了Java虚拟机中的方法调用机制,包括方法调用字节码指令、解析调用、分派调用。重点讲述了静态分派(方法重载)和动态分派(方法重写)的概念,以及动态类型语言支持下的java.lang.invoke包,特别是MethodHandle的使用及其与Reflection的区别。
摘要由CSDN通过智能技术生成

方法调用

Java 的方法的执行分为两个部分:

  • 方法调用:确定被调用的方法是哪一个;
  • 基于栈的解释执行:真正的执行方法的字节码。

在本节中我们将对方法调用进行详细的讲解,我们知道,一切方法的调用在 Class 文件中存储的都是常量池中的符号引用,而不是方法实际运行时的入口地址(直接引用),直到类加载的时候,甚至是实际运行的时候才回去会去确定要被运行的方法的直接引用,而确定要被运行的方法的直接引用的过程就叫做方法调用。

方法调用字节码指令

Java 虚拟机提供了 5 个职责不同的方法调用字节码指令:

  • invokestatic:调用静态方法;
  • invokespecial:调用构造器方法、私有方法、父类方法;
  • invokevirtual:调用所有虚方法,除了静态方法、构造器方法、私有方法、父类方法、final 方法的其他方法叫虚方法;
  • invokeinterface:调用接口方法,会在运行时确定一个该接口的实现对象;
  • invokedynamic:在运行时动态解析出调用点限定符引用的方法,再执行该方法。

除了 invokedynamic,其他 4 种方法的第一个参数都是被调用的方法的符号引用,是在编译时确定的,所以它们缺乏动态类型语言支持,因为动态类型语言只有在运行期才能确定接收者的类型,即变量的类型检查的主体过程在运行期,而非编译期。

final 方法虽然是通过 invokevirtual 调用的,但是其无法被覆盖,没有其他版本,无需对接收者进行多态选择,或者说多态选择的结果是唯一的,所以属于非虚方法。

解析调用

解析调用,正如其名,就是 在类加载的解析阶段,就确定了方法的调用版本 。我们知道类加载的解析阶段会将一部分符号引用转化为直接引用,这一过程就叫做解析调用。因为是在程序真正运行前就确定了要调用哪一个方法,所以 解析调用能成立的前提就是:方法在程序真正运行前就有一个明确的调用版本了,并且这个调用版本不会在运行期发生改变。

符合这两个要求的只有以下两类方法:

  • 通过 invokestatic 调用的方法:静态方法;
  • 通过 invokespecial 调用的方法:私有方法、构造器方法、父类方法;

这两类方法根本不可能通过继承或者别的方式重写出来其他版本,也就是说,在运行前就可以确定调用版本了,十分适合在类加载阶段就解析好。它们会在类加载的解析阶被解析为直接引用,即确定调用版本。

分派调用

在介绍分派调用前,我们先来介绍一下 Java 所具备的面向对象的 3 个基本特征:封装,继承,多态。

其中多态最基本的体现就是重载和重写了,重载和重写的一个重要特征就是方法名相同,其他各种不同:

  • 重载:发生在同一个类中,入参必须不同,返回类型、访问修饰符、抛出的异常都可以不同;
  • 重写:发生在子父类中,入参和返回类型必须相同,访问修饰符大于等于被重写的方法,不能抛出新的异常。

相同的方法名实际上给虚拟机的调用带来了困惑,因为虚拟机需要判断,它到底应该调用哪个方法,而这个过程会在分派调用中体现出来。其中:

  • 方法重载 —— 静态分派
  • 方法重写 —— 动态分派

静态分派(方法重载)

在介绍静态分派前,我们先来介绍一下什么是变量的静态类型和实际类型。

变量的静态类型和实际类型
public class StaticDispatch {
   
    static abstract class Human {
   
    }

    static class Man extends Human {
   
    }

    static class Woman extends Human {
   
    }

    public void sayHello(Human guy) {
   
    	System.out.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值