深入理解Java虚拟机——方法调用(解析调用)

x33g5p2x  于2022-03-28 转载在 Java  
字(0.9k)|赞(0)|评价(0)|浏览(201)

一、方法调用的概述

  • 方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法)。
  • 方法调用分为解析调用、静态分派调用和动态分派调用。

二、解析调用

2.1、解析调用的概述

  • 方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期是不可改变的。
  • 换句话说,调用目标在程序代码写好,编译器进行编译时就必须确定下来。这类方法的代用称为“解析”。

2.2、适合类加载阶段进行解析的方法

  • 在Java语言中符合“编译期可知,运行期不可变”这个要求的方法,主要包括静态方法和私有方法两大类,前者与类型直接关联,后者在外部不可被访问,这两种方法各自的特点决定了他们都不可能通过继承或别的方式重写其他版本。

2.3、java虚拟机提供的5条方法调用字节码指令

指令描述
invokestatic调用静态方法
invokespecial调用实例构造器< init>方法、私有方法和父类方法
invokevirtual调用所有的虚方法
invokeinterface调用接口方法,会在运行时再确定一个实现此接口的对象
invokedynamic先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法

2.4、非虚方法和虚方法的概述

  • 在解析阶段中确定唯一的调用版本,符合这个条件的有静态方法、私有方法、实例构造器、父类方法这4类,他们在类加载的时候就会把符号引用解析为该方法的直接引用,这些方法可以称为非虚方法
  • 与之相反,其他方法称为虚方法(除去final方法)。

2.5、方法静态调用解析的代码示例

  • 代码
public class Test1 {
    public static void hello(){
        System.out.println("hello world !");
    }

    public static void main(String[] args) {
        Test1.hello();
    }
}
  • 执行javac命令编译成.class文件

  • 执行javap命令查看字节码指令

  • 总结
    由上图可知,使用javap命令查看这段程序的字节码,会发现的确是通过invikestatic命令来调用hello()方法的。

相关文章