`

虚拟机字节码执行(一)方法调用

 
阅读更多

        在Java源文件编译为Class文件时,并不包含传统编译中的“连接”步骤。即一切方法调用在Class文件中都只是符号引用,而不是真正的指向方法在实际运行内存布局中的入口地址(相当于类加载过程中“解析”步骤中的直接引用)。因此才给Java带来强大的动态拓展能力,但也使Java的方法调用过程变得复杂,需要类在加载期间甚至在运行期间才能确定调用目标方法的直接引用。

 

        方法调用过程包括以下几个步骤:

 

解析

        因为所有的方法调用的目标方法在Class文件中都是一个常量池中的符号引用,在类加载的解析阶段,这些符号引用中的一部分会被翻译为直接引用。这种解析能够成立的前提是:方法在程序真正运行之前就有一个可确定的执行版本(也就是具体哪一个方法),并且这个方法在程序运行过程中不会被改变。换句话说,调用目标在程序代码写好、编译器进行编译时就已经能够确定下来。这类方法的调用称为“解析”。

Java语言中符合“编译期可知,运行时期不可变”要求的方法主要有静态方法和私有方法两大类,前者直接与类型关联,后者由于外部不可访问,所以这两种方法都不可能通过继承或者别的方式重写出其他版本,因此他们都适合在编译期进行解析。

 

Java虚拟机中提供了4条方法调用字节码指令(这里是jdk1.6标准)

  • invokestatic:调用静态方法。
  • invokespecial:调用实例构造器<init>方法、私有方法和父类方法。
  • invokevirtual:调用所有虚方法。
  • invokeinterface:调用接口方法,会在运行时再确定一个实现此接口的对象。

        只要能被invokestatic和invokespecial指令调用的方法,都可以在解析阶段确定唯一版本,符合这个条件的有静态方法,私有方法,构造器和父类方法。它们在类加载的时候就会把符号引用解析为该方法的直接引用。这些方法也称作“非虚方法”,与之相反的方法(除了final修饰过的)被称为虚方法。

 

        解析调用一定是一个静态过程,在编译期间就可以完全确定。

 

分派

 

静态分派

        静态分派主要是牵涉到类的重载(Overload)。在说明重载问题之前,先按如下代码定义两个重要的概念:

Animal rabbit = new Rabbit();

 


上述代码中,“Animal ”被称为变量的静态类型(Static Type)或者外观类型(Apparent Type),后面的“Rabbit”被称为变量的实际类型(Actual Type)。静态类型是编译期可知的,而实际类型在运行期才可以确定。使用哪个重载版本,完全取决于传入参量的数量和数据类型。编译器在重载时是通过参数的静态类型而不是实际类型作为判定依据。而由于静态类型是不会变化的,所以,在编译阶段就已经明确了要调用哪个方法版本。

 

        静态分派选择的重载版本往往并不是唯一的,只能确定一个“更加合适”的版本。产生这种模糊结论的原因是因为字面量不需要定义,所以字面量没有显式的静态类型,它的静态类型只能通过语言上的规则去理解和推断。

 

动态分派

        它是多态性的另一个重要体现——重写(Override)。在运行期根据变量的实际类型来确定方法执行的版本。虚拟机在实现动态分派时采用的方法是,在类的方法区中建立一个“虚方法表”。虚方法表中存放着各个方法的实际入口地址,如果某个方法在子类中没有被重写,那么子类的虚方法表里面的入口地址就和父类相同方法的地址入口是一致的。如果子类重写了父类方法,子类方法表中的地址会被替换为指向子类实现版本的入口地址。

分享到:
评论

相关推荐

    虚拟机运行时栈帧的结构

    在虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,这个概念模型称为各种虚拟机执行引擎的统一外观. 在不同的虚拟机实现里,执行引擎在执行 java 代码的时候,可能会解释执行和编译执行等,但是从外观上来看,...

    精简版JVM总结.pdf

    对于 Java 方法,记录正在执行的虚拟机字节码指令的地址;对于 native 方法,记录值为空 (Undefined) 唯一一个Java 虚拟机规范中没有规定任何 OutOfMemoryError 的内存区域 Java 虚拟机栈 每个线程都有独自的...

    Java虚拟机

    第三部分分析了虚拟机的执行子系统,包括类文件结构、虚拟机类加载机制、虚拟机字节码执行引擎。第四部分讲解了程序的编译与代码的优化,阐述了泛型、自动装箱拆箱、条件编译等语法糖的原理;讲解了虚拟机的热点探测...

    Java虚拟机规范(第8版).pdf

    本书完整而准确地阐释了Java虚拟机各...例如对包含默认实现代码的接口方法所做的调用,还讲述了为支持类型注解及方法参数注解而对class文件格式所做的扩展,并阐明了class文件中各属性的含义,以及字节码验证的规则。

    java虚拟机规范

    《Java虚拟机规范(Java SE 8版)英文版》中完整地讲述了由Java SE 8所引入的新特性,例如对包含默认实现代码的接口方法所做的调用,以及为支持类型注解及方法参数注解而对class文件格式所做的扩展等,还阐明了class...

    Simple-VM:一个简单的基于java的虚拟机来学习字节码解释

    它处理 18 条基本字节码指令,包括在保留状态的同时调用函数。 查看 vm.Bytecode 以查看所有 18 条指令。 要运行程序,只需使用任何指令集创建一个 int[] 数组并将其交给 VM。 将trace属性设置为true将在程序运行时...

    Java虚拟机规范

    《Java虚拟机规范(Java SE 8版)英文版》中完整地讲述了由Java SE 8所引入的新特性,例如对包含默认实现代码的接口方法所做的调用,以及为支持类型注解及方法参数注解而对class文件格式所做的扩展等,还阐明了class...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 java虚拟机中内置的安全特性 3.6 安全管理器和java api 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10...

    Java虚拟机规范.Java SE 8版.zip

    《Java核心技术系列:Java虚拟机规范...例如对包含默认实现代码的接口方法所做的调用,还讲述了为支持类型注解及方法参数注解而对class文件格式所做的扩展,并阐明了class文件中各属性的含义,以及字节码验证的规则。

    Java虚拟机规范 Java SE 8版-带目录-pdf

    Java虚拟机规范 Java SE 8版-带目录-...例如对包含默认实现代码的接口方法所做的调用,还讲述了为支持类型注解及方法参数注解而对class文件格式所做的扩展,并阐明了class文件中各属性的含义,以及字节码验证的规则。

    深入Java虚拟机

    3.4.3 第三趟:字节码验证 3.4.4 第四趟:符号引用的验证 3.4.5 二进制兼容 3.5 Java虚拟机中内置的安全特性 3.6 安全管理器和Java API 3.7 代码签名和认证 3.8 一个代码签名示例 3.9 策略 3.10...

    java虚拟机规范 jdk8.

    例如对包含默认实现代码的接口方法所做的调用,还讲述了为支持类型注解及方法参数注解而对class文件格式所做的扩展,并阐明了class文件中各属性的含义,以及字节码验证的规则。  《Java核心技术系列:Java虚拟机...

    Java虚拟机(JVM)面试题(总结最全面的面试题!!!)

    Java虚拟机(JVM)面试题(总结最全面的面试题!...能不能解释一下方法区(重点理解)什么是JVM字节码执行引擎你听过直接内存吗?知道垃圾收集系统吗?堆栈的区别是什么?深拷贝和浅拷贝Java会存在内存泄漏吗?请说 收

    Java虚拟机规范 Java SE 8版

    《Java核心技术系列:Java虚拟机规范...例如对包含默认实现代码的接口方法所做的调用,还讲述了为支持类型注解及方法参数注解而对class文件格式所做的扩展,并阐明了class文件中各属性的含义,以及字节码验证的规则。

    Java虚拟机规范jdk8版

    《Java虚拟机规范(Java SE 8版)英文版》中完整地讲述了由Java SE 8所引入的新特性,例如对包含默认实现代码的接口方法所做的调用,以及为支持类型注解及方法参数注解而对class文件格式所做的扩展等,还阐明了class...

    asm操作指南(中文)

    ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 189 7.4.1 类与类加载器 / 189 7.4.2 双亲委派模型 / 191 7.4.3 破坏双亲委派模型 / 194 7.5 本章小结 / 197 第8章 虚拟机字节码执行引擎 / 198 8.1 概述 / 198 8.2 运行时栈帧结构 / 199 8.2.1 局部变量...

    计算机二级Java语言复习资料

    通过Java编译器编译生成的是二进制字节码文件,其扩展名为.class。 调用applet小程序的HTML文件的扩展名为.html或.htm。 2. Java语言的执行模式是半编译和半解释型。Java编写好的程序首先由编译器转换为标准字节...

    Java常见面试问题整理.docx

    3.本地方法栈:与虚拟机栈所发挥的作用是相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。 异常:同上。 线程共享:异常:OOM 内存...

Global site tag (gtag.js) - Google Analytics