魔数与版本
魔数,四个字节,唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件,Class文件的魔数是
0xCAFEBABE,
版本号,四个字节,前两个字节是此版本号,后两个字节是主版本号,Java的版本号从45开始,JDK1.1 之后每个大版本号在主版本上向上加1,可以推算jdk8 的主版本号是52,这让我想起来曾经某个JDK版本报错内容: unsupport version 52 ,
图为在jdk1.8编译出的class文件的二进制内容
常量池
1 | 此处常量池并不是 Java中的常量,而是class文件中的资源仓库,是占用空间最大的数据项目之一,表数据类型项目,在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值 |
访问标识
紧接着的两个字节代表访问标志
操作数栈
Java虚拟机的解释执行引擎被称为”基于栈的执行引擎”,其中所指的栈就是指-操作数栈。
不同于程序计数器,Java虚拟机没有寄存器,程序计数器也无法被程序指令直接访问。Java虚拟机的指令是从操作数栈中而不是从寄存器中取得操作数的,因此它的运行方式是基于栈的而不是基于寄存器的。虽然指令也可以从其他地方取得操作数,比如从字节码流中跟随在操作码(代表指令的字节)之后的字节中或从常量池中,但是主要还是从操作数栈中获得操作数。
对于基于栈的指令集来说,最大的优势是可移植,因为它的实现不依赖硬件,不足之处在于其运行效率相对于寄存器指令集来说会慢一点;而寄存器指令集的优缺点则刚好与基于栈的指令集相反。
1 | 基于寄存器的: |
指令的操作数分两种:一种是嵌入在指令中的,通常是指令字节后面的若干个字节;另一种是存放在操作数栈中的。为了区别,我们把前者叫做嵌入式操作数,把后者叫做栈内操作数。这两者的区别是:嵌入式操作数是在编译时就已经确定的,运行时不会改变,它和指令一样存放于类文件方法表的 Code 属性中;而操作数是运行时确定的,即程序在执行过程中动态生成的
- 基于栈的执行引擎 是别于寄存器的 执行方式
未完。。。