BiBi - JVM -7- Java类文件结构

From:深入理解Java虚拟机

  • 目录
    BiBi - JVM -0- 开篇
    BiBi - JVM -1- Java内存区域
    BiBi - JVM -2- 对象
    BiBi - JVM -3- 垃圾收集算法
    BiBi - JVM -4- HotSpot JVM
    BiBi - JVM -5- 垃圾回收器
    BiBi - JVM -6- 回收策略
    BiBi - JVM -7- Java类文件结构
    BiBi - JVM -8- 类加载机制
    BiBi - JVM -9- 类加载器
    BiBi - JVM -10- 虚拟机字节码
    BiBi - JVM -11- 编译期优化
    BiBi - JVM -12- 运行期优化
    BiBi - JVM -13- 并发

Java虚拟机具有平台无关【Window、Mac】和语言无关【Groovy、JPython、JRuby】的特性。Java虚拟机只与【Class文件】这种特定的二进制文件格式关联,不与任何语言绑定。所有会有javac编译器、groovyc编译器、jrubyc编译器等来产class文件。

Class文件

Class文件是一组以8位字节【64位】为基础单位的二进制流,之间没有添加任何分隔符。当遇到需要占用8位字节以上空间的数据项时,会按照高位在前的方式分割成若干个8位字节进行存储。

Javap是一个专门用于分析Class文件字节码的工具。

Class文件格式中只有两种数据类型:无符号数和表。
无符号:基本的数据类型,u1 u2【2个字节】 u4 u8,无符号数可以用来描述:数字、索引引用、数量值、字符串值等。
表:是由多个无符号数构成的复合数据类型,习惯以【_info】结尾。

当需要描述一类型但数量不定的多个数据时,会使用一个前置的容量计数器 + 若干这连续的数据项,称这为某一类型的集合

Class文件结构

  1. Class文件的头4个字节【0xCAFFBABE,咖啡宝贝】称为【魔数】,标识该文件是否为一个能被虚拟机接受的Class文件,即进行身份验证。

  2. 紧接着魔数的4个字节标识Class文件的版本号:其中第5、6字节是次版本号;第7、8字节是主版本号【Java的版本号从45开始】。该信息主要是为了版本兼容,高版本的JDK能兼容低版本的Class文件,但低版本的JDK不能运行高版本的Class文件。

  3. 紧接着版本号之后的是常量池入口,由于数量不固定,所以入口有一个u2类型的数据,代表常量池容量的计数值。如:0x0016,代表常量池中有21项常量。【只有常量池的索引从1开始】其中,第0项表示:不引用任何一个常量池的项目。常量池中主要存放两大常量:字面常量和符号引用。

字面常量:文本字符串、final常量值。
符号引用:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

虚拟机加载Class文件是动态连接的,即在Class文件中不会保存各个方法和字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换,无法得到真正的内存入口地址,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体内存地址之中。

  1. 紧接着的是:
    访问标志;
    类索引、父类索引、接口索引集合;
    字段表集合;
    方法表集合;
    属性表集合。【跟我们平时理解的「属性」不是一回事】

字节码指令

Java虚拟机规范描绘了Java虚拟机应有的共同程序存储格式:Class文件格式和字节码指令集。Java虚拟机的指令由一个字节【8位】长度的,代表着某种特定操作含义的数字【操作码】以及跟随其后的零至多个代表此操作所需参数【操作数】而构成。

Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,只有一个操作码。在Java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。如:iload、fload。

  • 加载和存储指令
  • 运算指令
  • 类型转换指令
  • 对象创建与访问指令
  • 操作数栈管理指令
  • 控制转移指令
  • 方法调用和返回指令
  • 异常处理指令
  • 同步指令

你可能感兴趣的:(BiBi - JVM -7- Java类文件结构)